summaryrefslogtreecommitdiffstats
path: root/contrib/python/pythran
diff options
context:
space:
mode:
authormaxim-yurchuk <[email protected]>2024-10-09 12:29:46 +0300
committermaxim-yurchuk <[email protected]>2024-10-09 13:14:22 +0300
commit9731d8a4bb7ee2cc8554eaf133bb85498a4c7d80 (patch)
treea8fb3181d5947c0d78cf402aa56e686130179049 /contrib/python/pythran
parenta44b779cd359f06c3ebbef4ec98c6b38609d9d85 (diff)
publishFullContrib: true for ydb
<HIDDEN_URL> commit_hash:c82a80ac4594723cebf2c7387dec9c60217f603e
Diffstat (limited to 'contrib/python/pythran')
-rw-r--r--contrib/python/pythran/.yandex_meta/yamaker.yaml12
-rw-r--r--contrib/python/pythran/bin/ya.make5
-rw-r--r--contrib/python/pythran/patches/01-arcadia.patch12
-rw-r--r--contrib/python/pythran/pythran/pythonic/__dispatch__/clear.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/__dispatch__/conjugate.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/__dispatch__/copy.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/__dispatch__/count.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/__dispatch__/index.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/__dispatch__/pop.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/__dispatch__/remove.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/__dispatch__/sort.hpp38
-rw-r--r--contrib/python/pythran/pythran/pythonic/__dispatch__/update.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/bisect/bisect.hpp35
-rw-r--r--contrib/python/pythran/pythran/pythonic/bisect/bisect_left.hpp30
-rw-r--r--contrib/python/pythran/pythran/pythonic/bisect/bisect_right.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/ArithmeticError.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/AssertionError.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/AttributeError.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/BaseException.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/BufferError.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/BytesWarning.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/DeprecationWarning.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/EOFError.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/EnvironmentError.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/Exception.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/False.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/FileNotFoundError.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/FloatingPointError.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/FutureWarning.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/GeneratorExit.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/IOError.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/ImportError.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/ImportWarning.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/IndentationError.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/IndexError.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/KeyboardInterrupt.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/LookupError.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/NameError.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/OSError.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/OverflowError.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/PendingDeprecationWarning.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/ReferenceError.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/RuntimeWarning.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/StopIteration.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/SyntaxError.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/SyntaxWarning.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/SystemError.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/SystemExit.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/TabError.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/True.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/TypeError.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/UnboundLocalError.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/UnicodeError.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/UnicodeWarning.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/UserWarning.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/Warning.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/abs.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/all.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/any.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/assert.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/bin.hpp64
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/chr.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/complex.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/complex/conjugate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/dict/clear.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/dict/copy.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/dict/fromkeys.hpp34
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/dict/get.hpp39
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/dict/items.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/dict/keys.hpp30
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/dict/pop.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/dict/popitem.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/dict/setdefault.hpp44
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/dict/update.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/dict/values.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/divmod.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/enumerate.hpp117
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/file.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/file/close.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/file/fileno.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/file/flush.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/file/isatty.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/file/next.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/file/read.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/file/readline.hpp30
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/file/readlines.hpp33
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/file/seek.hpp39
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/file/tell.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/file/truncate.hpp39
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/file/write.hpp30
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/file/writelines.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/filter.hpp130
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/float_/is_integer.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/hex.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/isinstance.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/iter.hpp61
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/list/count.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/list/extend.hpp39
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/list/insert.hpp33
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/list/pop.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/list/remove.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/list/reverse.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/list/sort.hpp38
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/map.hpp223
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/next.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/oct.hpp32
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/open.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/ord.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/print.hpp58
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/pythran/StaticIfBreak.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/pythran/StaticIfCont.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/pythran/StaticIfNoReturn.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/pythran/StaticIfReturn.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/pythran/is_none.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/pythran/kwonly.hpp4
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/pythran/len_set.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/pythran/or_.hpp30
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/pythran/static_if.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/pythran/static_list.hpp42
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/reduce.hpp46
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/reversed.hpp60
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/round.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/set.hpp32
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/set/add.hpp35
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/set/clear.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/set/copy.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/set/difference.hpp56
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/set/difference_update.hpp43
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/set/discard.hpp36
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/set/intersection.hpp39
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/set/intersection_update.hpp44
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/set/isdisjoint.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/set/issubset.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/set/issuperset.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/set/remove.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/set/symmetric_difference.hpp39
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/set/symmetric_difference_update.hpp43
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/set/union_.hpp50
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/set/update.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/slice.hpp32
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/sorted.hpp70
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/str/__mod__.hpp58
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/str/capitalize.hpp32
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/str/count.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/str/endswith.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/str/find.hpp38
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/str/isalpha.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/str/isdigit.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/str/join.hpp118
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/str/lower.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/str/lstrip.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/str/replace.hpp53
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/str/rstrip.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/str/split.hpp72
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/str/startswith.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/str/strip.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/str/upper.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/sum.hpp49
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/type.hpp148
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/xrange.hpp108
-rw-r--r--contrib/python/pythran/pythran/pythonic/builtins/zip.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/cmath/acos.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/cmath/acosh.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/cmath/asin.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/cmath/asinh.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/cmath/atan.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/cmath/atanh.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/cmath/cos.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/cmath/cosh.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/cmath/e.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/cmath/exp.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/cmath/isinf.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/cmath/isnan.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/cmath/log.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/cmath/log10.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/cmath/pi.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/cmath/sin.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/cmath/sinh.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/cmath/sqrt.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/cmath/tan.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/cmath/tanh.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/functools/partial.hpp53
-rw-r--r--contrib/python/pythran/pythran/pythonic/functools/reduce.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/__dispatch__/clear.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/__dispatch__/conjugate.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/__dispatch__/copy.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/__dispatch__/count.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/__dispatch__/index.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/__dispatch__/pop.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/__dispatch__/remove.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/__dispatch__/sort.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/__dispatch__/update.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/bisect/bisect.hpp33
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/bisect/bisect_left.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/bisect/bisect_right.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/ArithmeticError.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/AssertionError.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/AttributeError.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/BaseException.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/BufferError.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/BytesWarning.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/DeprecationWarning.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/EOFError.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/EnvironmentError.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/Exception.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/False.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/FileNotFoundError.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/FloatingPointError.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/FutureWarning.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/GeneratorExit.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/IOError.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/ImportError.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/ImportWarning.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/IndentationError.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/IndexError.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/KeyboardInterrupt.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/LookupError.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/NameError.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/OSError.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/OverflowError.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/PendingDeprecationWarning.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/ReferenceError.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/RuntimeWarning.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/StopIteration.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/SyntaxError.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/SyntaxWarning.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/SystemError.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/SystemExit.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/TabError.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/True.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/TypeError.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/UnboundLocalError.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/UnicodeError.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/UnicodeWarning.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/UserWarning.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/Warning.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/abs.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/all.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/any.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/assert.hpp11
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/bin.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/chr.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/complex.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/complex/conjugate.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/dict/clear.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/dict/copy.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/dict/fromkeys.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/dict/get.hpp35
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/dict/items.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/dict/keys.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/dict/pop.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/dict/popitem.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/dict/setdefault.hpp32
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/dict/update.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/dict/values.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/divmod.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/enumerate.hpp75
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/file.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/file/close.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/file/fileno.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/file/flush.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/file/isatty.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/file/next.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/file/read.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/file/readline.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/file/readlines.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/file/seek.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/file/tell.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/file/truncate.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/file/write.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/file/writelines.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/filter.hpp91
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/float_/is_integer.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/hex.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/isinstance.hpp63
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/iter.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/list/count.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/list/extend.hpp32
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/list/insert.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/list/pop.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/list/remove.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/list/reverse.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/list/sort.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/map.hpp151
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/next.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/oct.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/open.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/ord.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/print.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/pythran/StaticIfBreak.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/pythran/StaticIfCont.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/pythran/StaticIfNoReturn.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/pythran/StaticIfReturn.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/pythran/is_none.hpp132
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/pythran/len_set.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/pythran/or_.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/pythran/static_if.hpp91
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/pythran/static_list.hpp44
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/reduce.hpp42
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/reversed.hpp38
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/round.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/set.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/set/add.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/set/clear.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/set/copy.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/set/difference.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/set/difference_update.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/set/discard.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/set/intersection.hpp33
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/set/intersection_update.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/set/isdisjoint.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/set/issubset.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/set/issuperset.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/set/remove.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/set/symmetric_difference.hpp35
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/set/symmetric_difference_update.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/set/union_.hpp35
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/set/update.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/slice.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/sorted.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/str/__mod__.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/str/capitalize.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/str/count.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/str/endswith.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/str/find.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/str/isalpha.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/str/isdigit.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/str/join.hpp46
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/str/lower.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/str/lstrip.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/str/replace.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/str/rstrip.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/str/split.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/str/startswith.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/str/strip.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/str/upper.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/sum.hpp59
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/type.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/xrange.hpp57
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/builtins/zip.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/cmath/acos.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/cmath/acosh.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/cmath/asin.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/cmath/asinh.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/cmath/atan.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/cmath/atanh.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/cmath/cos.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/cmath/cosh.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/cmath/e.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/cmath/exp.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/cmath/isinf.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/cmath/isnan.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/cmath/log.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/cmath/log10.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/cmath/pi.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/cmath/sin.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/cmath/sinh.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/cmath/sqrt.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/cmath/tan.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/cmath/tanh.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/functools/partial.hpp64
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/functools/reduce.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/close.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/fileno.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/flush.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/isatty.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/next.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/read.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/readline.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/readlines.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/seek.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/tell.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/truncate.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/write.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/writelines.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/itertools/combinations.hpp85
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/itertools/common.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/itertools/count.hpp65
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/itertools/ifilter.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/itertools/islice.hpp81
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/itertools/permutations.hpp111
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/itertools/product.hpp92
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/itertools/repeat.hpp61
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/acos.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/acosh.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/asin.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/asinh.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/atan.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/atan2.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/atanh.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/ceil.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/copysign.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/cos.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/cosh.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/degrees.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/e.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/erf.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/erfc.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/exp.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/expm1.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/fabs.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/factorial.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/floor.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/fmod.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/frexp.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/gamma.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/hypot.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/isinf.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/isnan.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/ldexp.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/lgamma.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/log.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/log10.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/log1p.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/modf.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/pi.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/pow.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/radians.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/sin.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/sinh.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/sqrt.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/tan.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/tanh.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/math/trunc.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/NINF.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/absolute.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/add.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/add/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/add/reduce.hpp10
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/alen.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/all.hpp41
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/allclose.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/alltrue.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/amax.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/amin.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/angle.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/angle_in_deg.hpp32
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/angle_in_rad.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/any.hpp41
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/append.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/arange.hpp194
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/arccos.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/arccosh.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/arcsin.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/arcsinh.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/arctan.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/arctan2/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/arctanh.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/argmax.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/argmin.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/argsort.hpp30
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/argwhere.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/around.hpp46
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/array2string.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/array_equal.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/array_equiv.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/array_split.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/array_str.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/asarray_chkfinite.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ascontiguousarray.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/asscalar.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/atleast_1d.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/atleast_2d.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/atleast_3d.hpp45
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/average.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/base_repr.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/binary_repr.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/bincount.hpp33
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_and.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_and/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_and/reduce.hpp10
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_or.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_or/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_or/reduce.hpp10
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_xor.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_xor/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_xor/reduce.hpp10
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/broadcast_to.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/byte.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/cbrt.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/clip.hpp51
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/complex.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/concatenate.hpp30
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/convolve.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/copy.hpp43
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/copysign.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/copysign/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/correlate.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/cosh.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/count_nonzero.hpp30
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/cross.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ctypeslib/as_array.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/cumprod.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/cumproduct.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/cumsum.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/deg2rad.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/degrees.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/delete_.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/diag.hpp32
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/diagflat.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/diagonal.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/diff.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/digitize.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/divide.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/divide/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/dot.hpp284
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/double_.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/dtype/type.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/e.hpp12
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ediff1d.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/equal.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/equal/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/expm1.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/eye.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fabs.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fft/c2c.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fft/fft.hpp55
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fft/fftn.hpp69
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fft/hfft.hpp90
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fft/ifft.hpp118
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fft/ihfft.hpp90
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fft/irfft.hpp90
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fft/rfft.hpp90
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fill_diagonal.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/finfo.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fix.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/flatnonzero.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/flip.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fliplr.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/flipud.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/float128.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/float_.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/floor_divide/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fmax.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fmax/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fmax/reduce.hpp10
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fmin.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fmin/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fmin/reduce.hpp10
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fmod.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fmod/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/frexp.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fromfile.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fromfunction.hpp47
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fromiter.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/fromstring.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/full.hpp42
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/full_like.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/greater.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/greater/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/greater_equal.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/greater_equal/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/heaviside.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/heaviside/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/hstack.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/hypot.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/hypot/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/identity.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/imag.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/indices.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/inner.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/insert.hpp51
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/int_.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/intc.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/interp.hpp100
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/intersect1d.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/invert.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/isclose.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/iscomplex.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/isfinite.hpp32
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/isinf.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/isnan.hpp32
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/isneginf.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/isposinf.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/isreal.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/isrealobj.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/isscalar.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/issctype.hpp30
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ldexp.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ldexp/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/left_shift.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/left_shift/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/less.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/less/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/less_equal.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/less_equal/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/lexsort.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/linalg/matrix_power.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/linspace.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/log10.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/log1p.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/log2.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/logaddexp.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/logaddexp/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/logaddexp2.hpp30
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/logaddexp2/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/logical_and.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/logical_and/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/logical_not.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/logical_or.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/logical_or/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/logical_xor.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/logical_xor/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/logspace.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/longlong.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/maximum/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/maximum/reduce.hpp10
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/mean.hpp64
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/minimum/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/minimum/reduce.hpp10
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/mod/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/multiply.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/multiply/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/multiply/reduce.hpp10
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/nan.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/nan_to_num.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/nanargmax.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/nanargmin.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/nanmax.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/nanmin.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/nansum.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ndarray.hpp30
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/astype.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/flatten.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/item.hpp30
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/reshape.hpp36
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/tofile.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/tolist.hpp42
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/tostring.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/view.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ndenumerate.hpp54
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ndim.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ndindex.hpp58
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/negative.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/negative/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/newaxis.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/nextafter.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/nextafter/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/not_equal.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/not_equal/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ones_like.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/outer.hpp34
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/partial_sum.hpp38
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/pi.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/place.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/power/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/product.hpp13
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ptp.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/put.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/putmask.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/rad2deg.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/radians.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/binomial.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/bytes.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/chisquare.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/choice.hpp51
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/dirichlet.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/exponential.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/f.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/gamma.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/generator.hpp102
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/geometric.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/gumbel.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/laplace.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/logistic.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/lognormal.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/logseries.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/negative_binomial.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/normal.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/pareto.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/poisson.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/power.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/rand.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/randint.hpp39
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/randn.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/random.hpp33
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/random_integers.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/random_sample.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/ranf.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/rayleigh.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/sample.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/seed.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/shuffle.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/standard_exponential.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/standard_gamma.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/standard_normal.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/uniform.hpp30
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/random/weibull.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ravel.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/reciprocal.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/remainder.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/remainder/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/repeat.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/resize.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/right_shift.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/right_shift/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/rint.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/rollaxis.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/rot90.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/round.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/round_.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/searchsorted.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/select.hpp51
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/setdiff1d.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/shape.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/short_.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/sign.hpp36
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/signbit.hpp30
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/sinh.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/size.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/sometrue.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/sort_complex.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/spacing.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/split.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/stack.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/std_.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/subtract.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/subtract/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/swapaxes.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/take.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/tan.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/tanh.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/tile.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/trace.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/tri.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/tril.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/trim_zeros.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/triu.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/true_divide.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/true_divide/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/trunc.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ubyte.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ufunc_accumulate.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ufunc_reduce.hpp42
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/uint.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/uintc.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/uintp.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ulonglong.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/union1d.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/unique.hpp113
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/unravel_index.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/unwrap.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/ushort.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/var.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/vdot.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/vectorize.hpp35
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/vstack.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/where.hpp33
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/zeros.hpp33
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/numpy/zeros_like.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/omp/get_num_threads.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/omp/get_thread_num.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/omp/get_wtick.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/omp/get_wtime.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/omp/in_parallel.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/omp/set_nested.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/omp/set_num_threads.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__abs__.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__add__.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__and__.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__concat__.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__contains__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__delitem__.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__div__.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__eq__.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__floordiv__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__ge__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__getitem__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__gt__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__iadd__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__iand__.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__iconcat__.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__idiv__.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__ifloordiv__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__ilshift__.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__imod__.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__imul__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__inv__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__invert__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__ior__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__ipow__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__irshift__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__isub__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__itruediv__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__ixor__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__le__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__lshift__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__lt__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__matmul__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__mod__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__mul__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__ne__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__neg__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__not__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__or__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__pos__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__rshift__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__sub__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__truediv__.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/__xor__.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/abs.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/concat.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/contains.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/countOf.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/delitem.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/getitem.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/iconcat.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/ifloordiv.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/ilshift.hpp9
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/imatmul.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/imod.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/indexOf.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/inv.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/invert.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/ipow.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/irshift.hpp9
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/is_.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/is_not.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/itemgetter.hpp50
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/itruediv.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/matmul.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/truediv.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/operator_/truth.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/os/path/join.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/random/choice.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/random/expovariate.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/random/gauss.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/random/randint.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/random/random.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/random/randrange.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/random/sample.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/random/seed.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/random/shuffle.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/random/uniform.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/scipy/special/binom.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/scipy/special/gamma.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/scipy/special/gammaincinv.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/scipy/special/gammaln.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/scipy/special/hankel1.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/scipy/special/hankel2.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/scipy/special/i0.hpp73
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/scipy/special/i0e.hpp30
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/scipy/special/iv.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/scipy/special/ivp.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/scipy/special/jv.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/scipy/special/jvp.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/scipy/special/kv.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/scipy/special/kvp.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/scipy/special/ndtr.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/scipy/special/ndtri.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/scipy/special/spherical_jn.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/scipy/special/spherical_yn.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/scipy/special/yv.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/scipy/special/yvp.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/string/ascii_letters.hpp15
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/string/ascii_lowercase.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/string/ascii_uppercase.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/string/digits.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/string/find.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/string/hexdigits.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/string/octdigits.hpp14
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/time/sleep.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/time/time.hpp17
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/types/cfun.hpp46
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/types/clongdouble.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/types/complex256.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/types/complex64.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/types/file.hpp131
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/types/finfo.hpp34
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/types/float128.hpp4
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/types/immediate.hpp33
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/types/int16.hpp4
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/types/intc.hpp4
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/types/intp.hpp4
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/types/longdouble.hpp4
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/types/numpy_ufunc.hpp39
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/types/static_if.hpp301
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/types/uint16.hpp4
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/types/uint32.hpp4
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/types/uint64.hpp4
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/types/uint8.hpp4
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/types/uintc.hpp4
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/types/uintp.hpp4
-rw-r--r--contrib/python/pythran/pythran/pythonic/include/utils/tags.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/close.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/fileno.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/flush.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/isatty.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/next.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/read.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/readline.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/readlines.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/seek.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/tell.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/truncate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/write.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/writelines.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/itertools/combinations.hpp133
-rw-r--r--contrib/python/pythran/pythran/pythonic/itertools/common.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/itertools/count.hpp103
-rw-r--r--contrib/python/pythran/pythran/pythonic/itertools/ifilter.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/itertools/islice.hpp128
-rw-r--r--contrib/python/pythran/pythran/pythonic/itertools/permutations.hpp178
-rw-r--r--contrib/python/pythran/pythran/pythonic/itertools/product.hpp144
-rw-r--r--contrib/python/pythran/pythran/pythonic/itertools/repeat.hpp82
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/acos.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/acosh.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/asin.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/asinh.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/atan.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/atan2.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/atanh.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/ceil.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/copysign.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/cos.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/cosh.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/degrees.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/e.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/erf.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/erfc.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/exp.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/expm1.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/fabs.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/factorial.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/floor.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/fmod.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/frexp.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/gamma.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/hypot.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/isinf.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/isnan.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/ldexp.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/lgamma.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/log.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/log10.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/log1p.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/modf.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/pi.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/pow.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/radians.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/sin.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/sinh.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/sqrt.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/tan.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/tanh.hpp16
-rw-r--r--contrib/python/pythran/pythran/pythonic/math/trunc.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/NINF.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/absolute.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/add.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/add/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/add/reduce.hpp11
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/alen.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/all.hpp98
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/allclose.hpp54
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/alltrue.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/amax.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/amin.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/angle.hpp34
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/angle_in_deg.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/angle_in_rad.hpp36
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/any.hpp99
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/append.hpp61
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/arange.hpp38
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/arccos.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/arccosh.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/arcsin.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/arcsinh.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/arctan.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/arctan2/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/arctanh.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/argmax.hpp47
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/argmin.hpp48
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/argminmax.hpp281
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/argsort.hpp95
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/argwhere.hpp46
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/around.hpp63
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/array2string.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/array_equal.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/array_equiv.hpp51
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/array_split.hpp63
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/array_str.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/asarray_chkfinite.hpp33
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ascontiguousarray.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/asscalar.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/atleast_1d.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/atleast_2d.hpp51
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/atleast_3d.hpp73
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/average.hpp38
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/base_repr.hpp52
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/binary_repr.hpp48
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/bincount.hpp60
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/bitwise_and.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/bitwise_and/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/bitwise_and/reduce.hpp11
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/bitwise_or.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/bitwise_or/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/bitwise_or/reduce.hpp11
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/bitwise_xor.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/bitwise_xor/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/bitwise_xor/reduce.hpp11
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/broadcast_to.hpp35
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/byte.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/cbrt.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/clip.hpp47
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/complex.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/concatenate.hpp198
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/convolve.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/copy.hpp58
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/copysign.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/copysign/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/correlate.hpp120
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/cosh.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/count_nonzero.hpp51
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/cross.hpp148
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ctypeslib/as_array.hpp32
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/cumprod.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/cumproduct.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/cumsum.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/deg2rad.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/degrees.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/delete_.hpp49
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/diag.hpp64
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/diagflat.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/diagonal.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/diff.hpp66
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/digitize.hpp56
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/divide.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/divide/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/dot.hpp604
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/double_.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/dtype/type.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/e.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ediff1d.hpp34
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/equal.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/equal/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/expm1.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/eye.hpp38
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fabs.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fft/c2c.hpp310
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fft/fft.hpp77
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fft/fftn.hpp145
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fft/hfft.hpp107
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fft/ifft.hpp147
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fft/ihfft.hpp106
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fft/irfft.hpp107
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fft/pocketfft.hpp3933
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fft/rfft.hpp106
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fill_diagonal.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/finfo.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fix.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/flatnonzero.hpp44
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/flip.hpp36
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fliplr.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/flipud.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/float128.hpp36
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/float_.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/floor_divide/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fmax.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fmax/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fmax/reduce.hpp11
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fmin.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fmin/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fmin/reduce.hpp11
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fmod.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fmod/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/frexp.hpp62
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fromfile.hpp51
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fromfunction.hpp69
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fromiter.hpp35
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/fromstring.hpp56
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/full.hpp61
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/full_like.hpp32
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/greater.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/greater/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/greater_equal.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/greater_equal/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/heaviside.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/heaviside/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/hstack.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/hypot.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/hypot/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/identity.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/imag.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/indices.hpp49
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/inner.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/insert.hpp79
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/int_.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/intc.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/interp.hpp198
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/interp_core.hpp258
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/intersect1d.hpp45
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/invert.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/isclose.hpp36
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/iscomplex.hpp39
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/isfinite.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/isinf.hpp33
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/isnan.hpp44
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/isneginf.hpp30
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/isposinf.hpp30
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/isreal.hpp39
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/isrealobj.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/isscalar.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/issctype.hpp32
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ldexp.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ldexp/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/left_shift.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/left_shift/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/less.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/less/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/less_equal.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/less_equal/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/lexsort.hpp68
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/linalg/matrix_power.hpp62
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/linspace.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/log10.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/log1p.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/log2.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/logaddexp.hpp32
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/logaddexp/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/logaddexp2.hpp36
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/logaddexp2/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/logical_and.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/logical_and/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/logical_not.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/logical_or.hpp30
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/logical_or/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/logical_xor.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/logical_xor/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/logspace.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/longlong.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/maximum/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/maximum/reduce.hpp11
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/mean.hpp54
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/minimum/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/minimum/reduce.hpp11
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/mod/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/multiply.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/multiply/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/multiply/reduce.hpp11
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/nan.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/nan_to_num.hpp42
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/nanargmax.hpp56
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/nanargmin.hpp57
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/nanmax.hpp55
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/nanmin.hpp55
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/nansum.hpp40
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ndarray.hpp38
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ndarray/astype.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ndarray/flatten.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ndarray/item.hpp43
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ndarray/reshape.hpp99
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ndarray/tofile.hpp43
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ndarray/tolist.hpp43
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ndarray/tostring.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ndarray/view.hpp30
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ndenumerate.hpp115
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ndim.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ndindex.hpp121
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/negative.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/negative/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/newaxis.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/nextafter.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/nextafter/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/not_equal.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/not_equal/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ones_like.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/outer.hpp57
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/partial_sum.hpp121
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/pi.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/place.hpp51
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/power/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/product.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ptp.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/put.hpp49
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/putmask.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/rad2deg.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/radians.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/binomial.hpp55
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/bytes.hpp33
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/chisquare.hpp46
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/choice.hpp123
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/dirichlet.hpp46
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/exponential.hpp47
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/f.hpp51
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/gamma.hpp46
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/geometric.hpp45
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/gumbel.hpp49
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/laplace.hpp54
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/logistic.hpp50
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/lognormal.hpp47
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/logseries.hpp69
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/negative_binomial.hpp47
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/normal.hpp45
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/pareto.hpp48
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/poisson.hpp45
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/power.hpp47
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/rand.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/randint.hpp67
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/randn.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/random.hpp45
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/random_integers.hpp34
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/random_sample.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/ranf.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/rayleigh.hpp47
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/sample.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/seed.hpp30
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/shuffle.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/standard_exponential.hpp42
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/standard_gamma.hpp42
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/standard_normal.hpp42
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/uniform.hpp47
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/random/weibull.hpp46
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ravel.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/reciprocal.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/remainder.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/remainder/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/repeat.hpp54
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/resize.hpp9
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/right_shift.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/right_shift/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/rint.hpp33
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/rollaxis.hpp43
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/rot90.hpp46
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/round.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/round_.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/searchsorted.hpp91
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/select.hpp123
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/setdiff1d.hpp88
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/shape.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/short_.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/sign.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/signbit.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/sinh.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/size.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/sometrue.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/sort_complex.hpp9
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/spacing.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/split.hpp41
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/stack.hpp72
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/std_.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/subtract.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/subtract/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/swapaxes.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/take.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/tan.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/tanh.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/tile.hpp79
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/trace.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/tri.hpp30
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/tril.hpp34
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/trim_zeros.hpp34
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/triu.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/true_divide.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/true_divide/accumulate.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/trunc.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ubyte.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ufunc_accumulate.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ufunc_reduce.hpp9
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/uint.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/uintc.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/uintp.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ulonglong.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/union1d.hpp47
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/unique.hpp447
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/unravel_index.hpp45
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/unwrap.hpp59
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/ushort.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/var.hpp86
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/vdot.hpp34
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/vectorize.hpp41
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/vstack.hpp35
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/where.hpp71
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/zeros.hpp49
-rw-r--r--contrib/python/pythran/pythran/pythonic/numpy/zeros_like.hpp31
-rw-r--r--contrib/python/pythran/pythran/pythonic/omp/get_num_threads.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/omp/get_thread_num.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/omp/get_wtick.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/omp/get_wtime.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/omp/in_parallel.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/omp/set_nested.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/omp/set_num_threads.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__abs__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__add__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__and__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__concat__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__contains__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__delitem__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__div__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__eq__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__floordiv__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__ge__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__getitem__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__gt__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__iadd__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__iand__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__iconcat__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__idiv__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__ifloordiv__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__ilshift__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__imod__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__imul__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__inv__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__invert__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__ior__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__ipow__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__irshift__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__isub__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__itruediv__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__ixor__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__le__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__lshift__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__lt__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__matmul__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__mod__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__mul__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__ne__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__neg__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__not__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__or__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__pos__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__rshift__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__sub__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__truediv__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/__xor__.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/abs.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/concat.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/contains.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/countOf.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/delitem.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/getitem.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/iconcat.hpp41
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/ifloordiv.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/ilshift.hpp12
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/imatmul.hpp28
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/imod.hpp26
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/indexOf.hpp29
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/inv.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/invert.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/ipow.hpp27
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/irshift.hpp12
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/is_.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/is_not.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/itemgetter.hpp80
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/itruediv.hpp35
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/matmul.hpp23
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/truediv.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/operator_/truth.hpp19
-rw-r--r--contrib/python/pythran/pythran/pythonic/os/path/join.hpp71
-rw-r--r--contrib/python/pythran/pythran/pythonic/random/choice.hpp49
-rw-r--r--contrib/python/pythran/pythran/pythonic/random/expovariate.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/random/gauss.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/random/randint.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/random/random.hpp21
-rw-r--r--contrib/python/pythran/pythran/pythonic/random/randrange.hpp32
-rw-r--r--contrib/python/pythran/pythran/pythonic/random/sample.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/random/seed.hpp30
-rw-r--r--contrib/python/pythran/pythran/pythonic/random/shuffle.hpp63
-rw-r--r--contrib/python/pythran/pythran/pythonic/random/uniform.hpp20
-rw-r--r--contrib/python/pythran/pythran/pythonic/scipy/special/binom.hpp40
-rw-r--r--contrib/python/pythran/pythran/pythonic/scipy/special/chbevl.hpp38
-rw-r--r--contrib/python/pythran/pythran/pythonic/scipy/special/gamma.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/scipy/special/gammaincinv.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/scipy/special/gammaln.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/scipy/special/hankel1.hpp36
-rw-r--r--contrib/python/pythran/pythran/pythonic/scipy/special/hankel2.hpp36
-rw-r--r--contrib/python/pythran/pythran/pythonic/scipy/special/i0.hpp43
-rw-r--r--contrib/python/pythran/pythran/pythonic/scipy/special/i0e.hpp42
-rw-r--r--contrib/python/pythran/pythran/pythonic/scipy/special/iv.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/scipy/special/ivp.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/scipy/special/jv.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/scipy/special/jvp.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/scipy/special/kv.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/scipy/special/kvp.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/scipy/special/ndtr.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/scipy/special/ndtri.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/scipy/special/spherical_jn.hpp45
-rw-r--r--contrib/python/pythran/pythran/pythonic/scipy/special/spherical_yn.hpp45
-rw-r--r--contrib/python/pythran/pythran/pythonic/scipy/special/yv.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/scipy/special/yvp.hpp37
-rw-r--r--contrib/python/pythran/pythran/pythonic/string/ascii_letters.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/string/ascii_lowercase.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/string/ascii_uppercase.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/string/digits.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/string/find.hpp22
-rw-r--r--contrib/python/pythran/pythran/pythonic/string/hexdigits.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/string/octdigits.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/time/sleep.hpp24
-rw-r--r--contrib/python/pythran/pythran/pythonic/time/time.hpp25
-rw-r--r--contrib/python/pythran/pythran/pythonic/types/cfun.hpp53
-rw-r--r--contrib/python/pythran/pythran/pythonic/types/clongdouble.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/types/complex256.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/types/complex64.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/types/file.hpp340
-rw-r--r--contrib/python/pythran/pythran/pythonic/types/finfo.hpp41
-rw-r--r--contrib/python/pythran/pythran/pythonic/types/float128.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/types/generator.hpp75
-rw-r--r--contrib/python/pythran/pythran/pythonic/types/int16.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/types/intc.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/types/intp.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/types/longdouble.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/types/pointer.hpp85
-rw-r--r--contrib/python/pythran/pythran/pythonic/types/static_if.hpp5
-rw-r--r--contrib/python/pythran/pythran/pythonic/types/uint16.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/types/uint32.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/types/uint64.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/types/uint8.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/types/uintc.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/types/uintp.hpp6
-rw-r--r--contrib/python/pythran/pythran/pythonic/utils/boost_local_config.hpp9
-rw-r--r--contrib/python/pythran/pythran/pythonic/utils/fwd.hpp18
-rw-r--r--contrib/python/pythran/pythran/pythonic/utils/tags.hpp7
-rw-r--r--contrib/python/pythran/pythran/pythonic/utils/yield.hpp28
-rw-r--r--contrib/python/pythran/pythran/xsimd/arch/xsimd_avx512cd.hpp28
-rw-r--r--contrib/python/pythran/pythran/xsimd/arch/xsimd_avx512dq.hpp212
1414 files changed, 44277 insertions, 0 deletions
diff --git a/contrib/python/pythran/.yandex_meta/yamaker.yaml b/contrib/python/pythran/.yandex_meta/yamaker.yaml
new file mode 100644
index 00000000000..eb09b5c93b4
--- /dev/null
+++ b/contrib/python/pythran/.yandex_meta/yamaker.yaml
@@ -0,0 +1,12 @@
+requirements:
+ - contrib/restricted/boost/format
+ - contrib/restricted/boost/math
+disable_includes:
+ - arm_sve.h
+ - xtl/xcomplex.hpp
+ - riscv_vector.h
+ - wasm_simd128.h
+exclude:
+ - pythran/boost/*
+ - pythran/pythonic/include/numpy/.hpp
+ - pythran/pythonic/numpy/.hpp
diff --git a/contrib/python/pythran/bin/ya.make b/contrib/python/pythran/bin/ya.make
new file mode 100644
index 00000000000..18caaa1ee83
--- /dev/null
+++ b/contrib/python/pythran/bin/ya.make
@@ -0,0 +1,5 @@
+SUBSCRIBER(g:python-contrib)
+
+RECURSE(
+ pythran
+)
diff --git a/contrib/python/pythran/patches/01-arcadia.patch b/contrib/python/pythran/patches/01-arcadia.patch
new file mode 100644
index 00000000000..89af882525b
--- /dev/null
+++ b/contrib/python/pythran/patches/01-arcadia.patch
@@ -0,0 +1,12 @@
+--- contrib/python/pythran/pythran/config.py (index)
++++ contrib/python/pythran/pythran/config.py (working tree)
+@@ -79,6 +79,9 @@ def init_cfg(sys_file, platform_file, user_file, config_args=None):
+ cfgp = ConfigParser()
+ for required in (sys_config_path, platform_config_path):
+ cfgp.read([required])
++ import pkgutil
++ for required in (sys_config_path, platform_config_path):
++ cfgp.read_string(pkgutil.get_data(__package__, os.path.basename(required)).decode("utf-8"))
+
+ if user_config_path:
+ cfgp.read([user_config_path])
diff --git a/contrib/python/pythran/pythran/pythonic/__dispatch__/clear.hpp b/contrib/python/pythran/pythran/pythonic/__dispatch__/clear.hpp
new file mode 100644
index 00000000000..d83c70b209d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/__dispatch__/clear.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_DISPATCH_CLEAR_HPP
+#define PYTHONIC_DISPATCH_CLEAR_HPP
+
+#include "pythonic/include/__dispatch__/clear.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace __dispatch__
+{
+
+ template <class Any>
+ auto clear(Any &&any) -> decltype(any.clear());
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/__dispatch__/conjugate.hpp b/contrib/python/pythran/pythran/pythonic/__dispatch__/conjugate.hpp
new file mode 100644
index 00000000000..0a21614138c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/__dispatch__/conjugate.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_DISPATCH_CONJUGATE_HPP
+#define PYTHONIC_DISPATCH_CONJUGATE_HPP
+
+#include "pythonic/include/__dispatch__/conjugate.hpp"
+
+#include "pythonic/numpy/conjugate.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace __dispatch__
+{
+ template <class Any>
+ auto conjugate(Any const &any) -> decltype(numpy::functor::conjugate{}(any))
+ {
+ return numpy::functor::conjugate{}(any);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/__dispatch__/copy.hpp b/contrib/python/pythran/pythran/pythonic/__dispatch__/copy.hpp
new file mode 100644
index 00000000000..70e59d1f383
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/__dispatch__/copy.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_DISPATCH_COPY_HPP
+#define PYTHONIC_DISPATCH_COPY_HPP
+
+#include "pythonic/include/__dispatch__/copy.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace __dispatch__
+{
+ template <class Any>
+ auto copy(Any const &any) -> decltype(any.copy())
+ {
+ return any.copy();
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/__dispatch__/count.hpp b/contrib/python/pythran/pythran/pythonic/__dispatch__/count.hpp
new file mode 100644
index 00000000000..5d350f6106e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/__dispatch__/count.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_DISPATCH_COUNT_HPP
+#define PYTHONIC_DISPATCH_COUNT_HPP
+
+#include "pythonic/include/__dispatch__/count.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace __dispatch__
+{
+
+ template <class Any, class Value>
+ auto count(Any &&any, Value &&value)
+ -> decltype(any.count(std::forward<Value>(value)))
+ {
+ return any.count(std::forward<Value>(value));
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/__dispatch__/index.hpp b/contrib/python/pythran/pythran/pythonic/__dispatch__/index.hpp
new file mode 100644
index 00000000000..e1827a80681
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/__dispatch__/index.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_DISPATCH_INDEX_HPP
+#define PYTHONIC_DISPATCH_INDEX_HPP
+
+#include "pythonic/include/__dispatch__/index.hpp"
+#include "pythonic/operator_/indexOf.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/__dispatch__/pop.hpp b/contrib/python/pythran/pythran/pythonic/__dispatch__/pop.hpp
new file mode 100644
index 00000000000..72c4aa474f2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/__dispatch__/pop.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_DISPATCH_POP_HPP
+#define PYTHONIC_DISPATCH_POP_HPP
+
+#include "pythonic/include/__dispatch__/pop.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace __dispatch__
+{
+ template <class Any, class... Arg0>
+ auto pop(Any &&any, Arg0 &&... arg0)
+ -> decltype(any.pop(std::forward<Arg0>(arg0)...))
+ {
+ return any.pop(std::forward<Arg0>(arg0)...);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/__dispatch__/remove.hpp b/contrib/python/pythran/pythran/pythonic/__dispatch__/remove.hpp
new file mode 100644
index 00000000000..60493e30384
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/__dispatch__/remove.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_DISPATCH_REMOVE_HPP
+#define PYTHONIC_DISPATCH_REMOVE_HPP
+
+#include "pythonic/include/__dispatch__/remove.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace __dispatch__
+{
+ template <class Any, class Arg0>
+ auto remove(Any &any, Arg0 const &arg0) -> decltype(any.remove(arg0))
+ {
+ return any.remove(arg0);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/__dispatch__/sort.hpp b/contrib/python/pythran/pythran/pythonic/__dispatch__/sort.hpp
new file mode 100644
index 00000000000..a49b8f8955a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/__dispatch__/sort.hpp
@@ -0,0 +1,38 @@
+#ifndef PYTHONIC_DISPATCH_SORT_HPP
+#define PYTHONIC_DISPATCH_SORT_HPP
+
+#include "pythonic/include/__dispatch__/sort.hpp"
+
+#include "pythonic/builtins/list/sort.hpp"
+#include "pythonic/numpy/sort.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace __dispatch__
+{
+
+ template <class T, class... Args>
+ auto sort(types::list<T> &l, Args &&... args)
+ -> decltype(pythonic::builtins::list::sort(l,
+ std::forward<Args>(args)...))
+ {
+ return pythonic::builtins::list::sort(l, std::forward<Args>(args)...);
+ }
+ template <class T, class... Args>
+ auto sort(types::list<T> &&l, Args &&... args)
+ -> decltype(pythonic::builtins::list::sort(std::move(l),
+ std::forward<Args>(args)...))
+ {
+ return pythonic::builtins::list::sort(std::move(l),
+ std::forward<Args>(args)...);
+ }
+ template <class Any, class... Args>
+ types::none_type sort(Any &&any, Args &&... args)
+ {
+ return pythonic::numpy::ndarray::sort(std::forward<Any>(any),
+ std::forward<Args>(args)...);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/__dispatch__/update.hpp b/contrib/python/pythran/pythran/pythonic/__dispatch__/update.hpp
new file mode 100644
index 00000000000..faae8c9a274
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/__dispatch__/update.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_DISPATCH_UPDATE_HPP
+#define PYTHONIC_DISPATCH_UPDATE_HPP
+
+#include "pythonic/include/__dispatch__/update.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace __dispatch__
+{
+
+ template <class Any, class... Arg0>
+ auto update(Any &&any, Arg0 &&... arg0)
+ -> decltype(any.update(std::forward<Arg0>(arg0)...))
+ {
+ return any.update(std::forward<Arg0>(arg0)...);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/bisect/bisect.hpp b/contrib/python/pythran/pythran/pythonic/bisect/bisect.hpp
new file mode 100644
index 00000000000..3efc50b943c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/bisect/bisect.hpp
@@ -0,0 +1,35 @@
+#ifndef PYTHONIC_BISECT_BISECT_HPP
+#define PYTHONIC_BISECT_BISECT_HPP
+
+#include "pythonic/include/bisect/bisect.hpp"
+#include "pythonic/builtins/ValueError.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+#include <iterator>
+
+PYTHONIC_NS_BEGIN
+
+namespace bisect
+{
+ template <class X, class A>
+ long bisect(X const &x, A const &a, long lo,
+ details::bisect_fun<X, A> const &fun)
+ {
+ if (lo < 0)
+ throw types::ValueError("lo must be non-negative");
+ return std::distance(x.begin(), fun(x.begin() + lo, x.end(), a));
+ }
+
+ template <class X, class A>
+ long bisect(X const &x, A const &a, long lo, long hi,
+ details::bisect_fun<X, A> const &fun)
+ {
+ if (lo < 0)
+ throw types::ValueError("lo must be non-negative");
+ return std::distance(x.begin(), fun(x.begin() + lo, x.begin() + hi, a));
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/bisect/bisect_left.hpp b/contrib/python/pythran/pythran/pythonic/bisect/bisect_left.hpp
new file mode 100644
index 00000000000..964c1126639
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/bisect/bisect_left.hpp
@@ -0,0 +1,30 @@
+#ifndef PYTHONIC_BISECT_BISECTLEFT_HPP
+#define PYTHONIC_BISECT_BISECTLEFT_HPP
+
+#include "pythonic/include/bisect/bisect_left.hpp"
+
+#include "pythonic/bisect/bisect.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+
+PYTHONIC_NS_BEGIN
+
+namespace bisect
+{
+ template <class X, class A>
+ long bisect_left(X const &x, A const &a, long lo)
+ {
+ return bisect(x, a, lo, std::lower_bound<typename X::const_iterator, A>);
+ }
+
+ template <class X, class A>
+ long bisect_left(X const &x, A const &a, long lo, long hi)
+ {
+ return bisect(x, a, lo, hi,
+ std::lower_bound<typename X::const_iterator, A>);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/bisect/bisect_right.hpp b/contrib/python/pythran/pythran/pythonic/bisect/bisect_right.hpp
new file mode 100644
index 00000000000..f82893d2fef
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/bisect/bisect_right.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_BISECT_BISECTRIGHT_HPP
+#define PYTHONIC_BISECT_BISECTRIGHT_HPP
+
+#include "pythonic/include/bisect/bisect_right.hpp"
+
+#include "pythonic/bisect/bisect.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace bisect
+{
+
+ template <class X, class A>
+ long bisect_right(X const &x, A const &a, long lo)
+ {
+ return bisect(x, a, lo);
+ }
+
+ template <class X, class A>
+ long bisect_right(X const &x, A const &a, long lo, long hi)
+ {
+ return bisect(x, a, lo, hi);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/ArithmeticError.hpp b/contrib/python/pythran/pythran/pythonic/builtins/ArithmeticError.hpp
new file mode 100644
index 00000000000..c50b321e4c0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/ArithmeticError.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_ARITHMETICERROR_HPP
+#define PYTHONIC_BUILTIN_ARITHMETICERROR_HPP
+
+#include "pythonic/include/builtins/ArithmeticError.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(ArithmeticError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/AssertionError.hpp b/contrib/python/pythran/pythran/pythonic/builtins/AssertionError.hpp
new file mode 100644
index 00000000000..0579af8b494
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/AssertionError.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_ASSERTIONERROR_HPP
+#define PYTHONIC_BUILTIN_ASSERTIONERROR_HPP
+
+#include "pythonic/include/builtins/AssertionError.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(AssertionError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/AttributeError.hpp b/contrib/python/pythran/pythran/pythonic/builtins/AttributeError.hpp
new file mode 100644
index 00000000000..9ffcb553a92
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/AttributeError.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_ATTRIBUTEERROR_HPP
+#define PYTHONIC_BUILTIN_ATTRIBUTEERROR_HPP
+
+#include "pythonic/include/builtins/AttributeError.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(AttributeError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/BaseException.hpp b/contrib/python/pythran/pythran/pythonic/builtins/BaseException.hpp
new file mode 100644
index 00000000000..792713018dc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/BaseException.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_BASEEXCEPTION_HPP
+#define PYTHONIC_BUILTIN_BASEEXCEPTION_HPP
+
+#include "pythonic/include/builtins/BaseException.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(BaseException)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/BufferError.hpp b/contrib/python/pythran/pythran/pythonic/builtins/BufferError.hpp
new file mode 100644
index 00000000000..6c6ca1d9f5d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/BufferError.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_BUFFERERROR_HPP
+#define PYTHONIC_BUILTIN_BUFFERERROR_HPP
+
+#include "pythonic/include/builtins/BufferError.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(BufferError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/BytesWarning.hpp b/contrib/python/pythran/pythran/pythonic/builtins/BytesWarning.hpp
new file mode 100644
index 00000000000..9c55aa6358b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/BytesWarning.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_BYTESWARNING_HPP
+#define PYTHONIC_BUILTIN_BYTESWARNING_HPP
+
+#include "pythonic/include/builtins/BytesWarning.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(BytesWarning)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/DeprecationWarning.hpp b/contrib/python/pythran/pythran/pythonic/builtins/DeprecationWarning.hpp
new file mode 100644
index 00000000000..b2c30046174
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/DeprecationWarning.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_DEPRECATIONWARNING_HPP
+#define PYTHONIC_BUILTIN_DEPRECATIONWARNING_HPP
+
+#include "pythonic/include/builtins/DeprecationWarning.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(DeprecationWarning)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/EOFError.hpp b/contrib/python/pythran/pythran/pythonic/builtins/EOFError.hpp
new file mode 100644
index 00000000000..b6980932bb3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/EOFError.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_EOFERROR_HPP
+#define PYTHONIC_BUILTIN_EOFERROR_HPP
+
+#include "pythonic/include/builtins/EOFError.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(EOFError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/EnvironmentError.hpp b/contrib/python/pythran/pythran/pythonic/builtins/EnvironmentError.hpp
new file mode 100644
index 00000000000..574925f1619
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/EnvironmentError.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_ENVIRONMENTERROR_HPP
+#define PYTHONIC_BUILTIN_ENVIRONMENTERROR_HPP
+
+#include "pythonic/include/builtins/EnvironmentError.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(EnvironmentError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/Exception.hpp b/contrib/python/pythran/pythran/pythonic/builtins/Exception.hpp
new file mode 100644
index 00000000000..56e796b6aa7
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/Exception.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_EXCEPTION_HPP
+#define PYTHONIC_BUILTIN_EXCEPTION_HPP
+
+#include "pythonic/include/builtins/Exception.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(Exception)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/False.hpp b/contrib/python/pythran/pythran/pythonic/builtins/False.hpp
new file mode 100644
index 00000000000..dec00582c5a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/False.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_BUILTIN_FALSE_HPP
+#define PYTHONIC_BUILTIN_FALSE_HPP
+
+#include "pythonic/include/builtins/False.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/FileNotFoundError.hpp b/contrib/python/pythran/pythran/pythonic/builtins/FileNotFoundError.hpp
new file mode 100644
index 00000000000..3aad3890241
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/FileNotFoundError.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_FILENOTFOUNDERROR_HPP
+#define PYTHONIC_BUILTIN_FILENOTFOUNDERROR_HPP
+
+#include "pythonic/include/builtins/FileNotFoundError.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(FileNotFoundError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/FloatingPointError.hpp b/contrib/python/pythran/pythran/pythonic/builtins/FloatingPointError.hpp
new file mode 100644
index 00000000000..2ddb1c6ec67
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/FloatingPointError.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_FLOATINGPOINTERROR_HPP
+#define PYTHONIC_BUILTIN_FLOATINGPOINTERROR_HPP
+
+#include "pythonic/include/builtins/FloatingPointError.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(FloatingPointError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/FutureWarning.hpp b/contrib/python/pythran/pythran/pythonic/builtins/FutureWarning.hpp
new file mode 100644
index 00000000000..9b7fcf0ea71
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/FutureWarning.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_FUTUREWARNING_HPP
+#define PYTHONIC_BUILTIN_FUTUREWARNING_HPP
+
+#include "pythonic/include/builtins/FutureWarning.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(FutureWarning)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/GeneratorExit.hpp b/contrib/python/pythran/pythran/pythonic/builtins/GeneratorExit.hpp
new file mode 100644
index 00000000000..3453a99f996
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/GeneratorExit.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_GENERATOREXIT_HPP
+#define PYTHONIC_BUILTIN_GENERATOREXIT_HPP
+
+#include "pythonic/include/builtins/GeneratorExit.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(GeneratorExit)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/IOError.hpp b/contrib/python/pythran/pythran/pythonic/builtins/IOError.hpp
new file mode 100644
index 00000000000..e1f5bde37b4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/IOError.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_IOERROR_HPP
+#define PYTHONIC_BUILTIN_IOERROR_HPP
+
+#include "pythonic/include/builtins/IOError.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(IOError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/ImportError.hpp b/contrib/python/pythran/pythran/pythonic/builtins/ImportError.hpp
new file mode 100644
index 00000000000..89d936d1618
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/ImportError.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_IMPORTERROR_HPP
+#define PYTHONIC_BUILTIN_IMPORTERROR_HPP
+
+#include "pythonic/include/builtins/ImportError.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(ImportError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/ImportWarning.hpp b/contrib/python/pythran/pythran/pythonic/builtins/ImportWarning.hpp
new file mode 100644
index 00000000000..78c577eac74
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/ImportWarning.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_IMPORTWARNING_HPP
+#define PYTHONIC_BUILTIN_IMPORTWARNING_HPP
+
+#include "pythonic/include/builtins/ImportWarning.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(ImportWarning)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/IndentationError.hpp b/contrib/python/pythran/pythran/pythonic/builtins/IndentationError.hpp
new file mode 100644
index 00000000000..b8d80972e30
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/IndentationError.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_INDENTATIONERROR_HPP
+#define PYTHONIC_BUILTIN_INDENTATIONERROR_HPP
+
+#include "pythonic/include/builtins/IndentationError.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(IndentationError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/IndexError.hpp b/contrib/python/pythran/pythran/pythonic/builtins/IndexError.hpp
new file mode 100644
index 00000000000..20a779c5eb6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/IndexError.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_INDEXERROR_HPP
+#define PYTHONIC_BUILTIN_INDEXERROR_HPP
+
+#include "pythonic/include/builtins/IndexError.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(IndexError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/KeyboardInterrupt.hpp b/contrib/python/pythran/pythran/pythonic/builtins/KeyboardInterrupt.hpp
new file mode 100644
index 00000000000..8ab4c2a73d3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/KeyboardInterrupt.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_KEYBOARDINTERRUPT_HPP
+#define PYTHONIC_BUILTIN_KEYBOARDINTERRUPT_HPP
+
+#include "pythonic/include/builtins/KeyboardInterrupt.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(KeyboardInterrupt)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/LookupError.hpp b/contrib/python/pythran/pythran/pythonic/builtins/LookupError.hpp
new file mode 100644
index 00000000000..014c737753d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/LookupError.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_LOOKUPERROR_HPP
+#define PYTHONIC_BUILTIN_LOOKUPERROR_HPP
+
+#include "pythonic/include/builtins/LookupError.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(LookupError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/NameError.hpp b/contrib/python/pythran/pythran/pythonic/builtins/NameError.hpp
new file mode 100644
index 00000000000..c62a92046ee
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/NameError.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_NAMEERROR_HPP
+#define PYTHONIC_BUILTIN_NAMEERROR_HPP
+
+#include "pythonic/include/builtins/NameError.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(NameError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/OSError.hpp b/contrib/python/pythran/pythran/pythonic/builtins/OSError.hpp
new file mode 100644
index 00000000000..b628d38e8bb
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/OSError.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_OSERROR_HPP
+#define PYTHONIC_BUILTIN_OSERROR_HPP
+
+#include "pythonic/include/builtins/OSError.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(OSError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/OverflowError.hpp b/contrib/python/pythran/pythran/pythonic/builtins/OverflowError.hpp
new file mode 100644
index 00000000000..fc1d17c7c7a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/OverflowError.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_OVERFLOWERROR_HPP
+#define PYTHONIC_BUILTIN_OVERFLOWERROR_HPP
+
+#include "pythonic/include/builtins/OverflowError.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(OverflowError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/PendingDeprecationWarning.hpp b/contrib/python/pythran/pythran/pythonic/builtins/PendingDeprecationWarning.hpp
new file mode 100644
index 00000000000..8dae6fc99e9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/PendingDeprecationWarning.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_PENDINGDEPRECATIONWARNING_HPP
+#define PYTHONIC_BUILTIN_PENDINGDEPRECATIONWARNING_HPP
+
+#include "pythonic/include/builtins/PendingDeprecationWarning.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(PendingDeprecationWarning)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/ReferenceError.hpp b/contrib/python/pythran/pythran/pythonic/builtins/ReferenceError.hpp
new file mode 100644
index 00000000000..7228a2a8b85
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/ReferenceError.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_REFERENCEERROR_HPP
+#define PYTHONIC_BUILTIN_REFERENCEERROR_HPP
+
+#include "pythonic/include/builtins/ReferenceError.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(ReferenceError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/RuntimeWarning.hpp b/contrib/python/pythran/pythran/pythonic/builtins/RuntimeWarning.hpp
new file mode 100644
index 00000000000..eabbe79a1f9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/RuntimeWarning.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_RUNTIMEWARNING_HPP
+#define PYTHONIC_BUILTIN_RUNTIMEWARNING_HPP
+
+#include "pythonic/include/builtins/RuntimeWarning.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(RuntimeWarning)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/StopIteration.hpp b/contrib/python/pythran/pythran/pythonic/builtins/StopIteration.hpp
new file mode 100644
index 00000000000..33dee02dfa6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/StopIteration.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_STOPITERATION_HPP
+#define PYTHONIC_BUILTIN_STOPITERATION_HPP
+
+#include "pythonic/include/builtins/StopIteration.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(StopIteration)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/SyntaxError.hpp b/contrib/python/pythran/pythran/pythonic/builtins/SyntaxError.hpp
new file mode 100644
index 00000000000..9f309fc75da
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/SyntaxError.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_SYNTAXERROR_HPP
+#define PYTHONIC_BUILTIN_SYNTAXERROR_HPP
+
+#include "pythonic/include/builtins/SyntaxError.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(SyntaxError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/SyntaxWarning.hpp b/contrib/python/pythran/pythran/pythonic/builtins/SyntaxWarning.hpp
new file mode 100644
index 00000000000..b6a00565a72
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/SyntaxWarning.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_SYNTAXWARNING_HPP
+#define PYTHONIC_BUILTIN_SYNTAXWARNING_HPP
+
+#include "pythonic/include/builtins/SyntaxWarning.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(SyntaxWarning)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/SystemError.hpp b/contrib/python/pythran/pythran/pythonic/builtins/SystemError.hpp
new file mode 100644
index 00000000000..c873c57d564
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/SystemError.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_SYSTEMERROR_HPP
+#define PYTHONIC_BUILTIN_SYSTEMERROR_HPP
+
+#include "pythonic/include/builtins/SystemError.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(SystemError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/SystemExit.hpp b/contrib/python/pythran/pythran/pythonic/builtins/SystemExit.hpp
new file mode 100644
index 00000000000..1621e1bf238
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/SystemExit.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_SYSTEMEXIT_HPP
+#define PYTHONIC_BUILTIN_SYSTEMEXIT_HPP
+
+#include "pythonic/include/builtins/SystemExit.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(SystemExit)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/TabError.hpp b/contrib/python/pythran/pythran/pythonic/builtins/TabError.hpp
new file mode 100644
index 00000000000..d4513c4a66c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/TabError.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_TABERROR_HPP
+#define PYTHONIC_BUILTIN_TABERROR_HPP
+
+#include "pythonic/include/builtins/TabError.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(TabError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/True.hpp b/contrib/python/pythran/pythran/pythonic/builtins/True.hpp
new file mode 100644
index 00000000000..b3267584832
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/True.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_BUILTIN_TRUE_HPP
+#define PYTHONIC_BUILTIN_TRUE_HPP
+
+#include "pythonic/include/builtins/True.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/TypeError.hpp b/contrib/python/pythran/pythran/pythonic/builtins/TypeError.hpp
new file mode 100644
index 00000000000..93c566c9595
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/TypeError.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_TYPEERROR_HPP
+#define PYTHONIC_BUILTIN_TYPEERROR_HPP
+
+#include "pythonic/include/builtins/TypeError.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(TypeError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/UnboundLocalError.hpp b/contrib/python/pythran/pythran/pythonic/builtins/UnboundLocalError.hpp
new file mode 100644
index 00000000000..ac8da236cbf
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/UnboundLocalError.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_UNBOUNDLOCALERROR_HPP
+#define PYTHONIC_BUILTIN_UNBOUNDLOCALERROR_HPP
+
+#include "pythonic/include/builtins/UnboundLocalError.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(UnboundLocalError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/UnicodeError.hpp b/contrib/python/pythran/pythran/pythonic/builtins/UnicodeError.hpp
new file mode 100644
index 00000000000..bc9e2d64fdd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/UnicodeError.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_UNICODEERROR_HPP
+#define PYTHONIC_BUILTIN_UNICODEERROR_HPP
+
+#include "pythonic/include/builtins/UnicodeError.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(UnicodeError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/UnicodeWarning.hpp b/contrib/python/pythran/pythran/pythonic/builtins/UnicodeWarning.hpp
new file mode 100644
index 00000000000..ee24e18d79a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/UnicodeWarning.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_UNICODEWARNING_HPP
+#define PYTHONIC_BUILTIN_UNICODEWARNING_HPP
+
+#include "pythonic/include/builtins/UnicodeWarning.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(UnicodeWarning)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/UserWarning.hpp b/contrib/python/pythran/pythran/pythonic/builtins/UserWarning.hpp
new file mode 100644
index 00000000000..c4a2ff735dd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/UserWarning.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_USERWARNING_HPP
+#define PYTHONIC_BUILTIN_USERWARNING_HPP
+
+#include "pythonic/include/builtins/UserWarning.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(UserWarning)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/Warning.hpp b/contrib/python/pythran/pythran/pythonic/builtins/Warning.hpp
new file mode 100644
index 00000000000..3988048e2a8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/Warning.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_BUILTIN_WARNING_HPP
+#define PYTHONIC_BUILTIN_WARNING_HPP
+
+#include "pythonic/include/builtins/Warning.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_IMPL(Warning)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/abs.hpp b/contrib/python/pythran/pythran/pythonic/builtins/abs.hpp
new file mode 100644
index 00000000000..1caa876d6ba
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/abs.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_BUILTIN_ABS_HPP
+#define PYTHONIC_BUILTIN_ABS_HPP
+
+#include "pythonic/include/builtins/abs.hpp"
+#include "pythonic/numpy/abs.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/all.hpp b/contrib/python/pythran/pythran/pythonic/builtins/all.hpp
new file mode 100644
index 00000000000..6fb8383595d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/all.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_BUILTIN_ALL_HPP
+#define PYTHONIC_BUILTIN_ALL_HPP
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/include/builtins/all.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ template <class Iterable>
+ bool all(Iterable &&s)
+ {
+ auto iend = s.end();
+ for (auto iter = s.begin(); iter != iend; ++iter)
+ if (!*iter)
+ return false;
+ return true;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/any.hpp b/contrib/python/pythran/pythran/pythonic/builtins/any.hpp
new file mode 100644
index 00000000000..d74e5c2ae2a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/any.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_BUILTIN_ANY_HPP
+#define PYTHONIC_BUILTIN_ANY_HPP
+
+#include "pythonic/include/builtins/any.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+ template <class Iterable>
+ bool any(Iterable &&s)
+ {
+ auto iend = s.end();
+ for (auto iter = s.begin(); iter != iend; ++iter)
+ if (*iter)
+ return true;
+ return false;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/assert.hpp b/contrib/python/pythran/pythran/pythonic/builtins/assert.hpp
new file mode 100644
index 00000000000..6bcbd3a972d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/assert.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_BUILTIN_ASSERT_HPP
+#define PYTHONIC_BUILTIN_ASSERT_HPP
+
+#include "pythonic/include/builtins/assert.hpp"
+
+#include "pythonic/builtins/AssertionError.hpp"
+#include "pythonic/types/str.hpp"
+
+PYTHONIC_NS_BEGIN
+
+inline void pythran_assert(bool cond)
+{
+#ifndef NDEBUG
+ if (!cond)
+ throw types::AssertionError();
+#endif
+}
+
+inline void pythran_assert(bool cond, types::str const &what)
+{
+#ifndef NDEBUG
+ if (!cond)
+ throw types::AssertionError(what);
+#endif
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/bin.hpp b/contrib/python/pythran/pythran/pythonic/builtins/bin.hpp
new file mode 100644
index 00000000000..f102c797003
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/bin.hpp
@@ -0,0 +1,64 @@
+#ifndef PYTHONIC_BUILTIN_BIN_HPP
+#define PYTHONIC_BUILTIN_BIN_HPP
+
+#include "pythonic/include/builtins/bin.hpp"
+
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+#include <cmath>
+#include <limits>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+ template <class T>
+ typename std::enable_if<std::is_scalar<T>::value, types::str>::type
+ bin(T const &v)
+ {
+ using UT = typename std::make_unsigned<T>::type;
+ if (v < T{0})
+ if (v == std::numeric_limits<T>::min()) {
+ // In this special case, calling -v would overflow so
+ // a special case is needed.
+ types::str res;
+ auto &backend = res.chars();
+ backend.resize(8 * sizeof(T) + 3);
+ auto it = backend.begin();
+ *it++ = '-';
+ *it++ = '0';
+ *it++ = 'b';
+ *it++ = '1';
+ std::fill(it, backend.end(), '0');
+ return res;
+ } else
+ return "-" + bin(-v);
+ else if (v == T{0})
+ return "0b0";
+ else {
+ // Due to rounding errors, we cannot use std::log2(v)
+ // to accuratly find length.
+ size_t len = (8 * sizeof(UT)) - 1;
+ UT i{UT{1} << len};
+ while (!(i & v)) {
+ i >>= 1;
+ len--;
+ }
+ types::str res;
+ res.reserve(2 + len);
+ auto &backend = res.chars();
+ backend.append("0b");
+ for (; i; i >>= 1)
+ if (v & i)
+ backend.append("1");
+ else
+ backend.append("0");
+ return res;
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/chr.hpp b/contrib/python/pythran/pythran/pythonic/builtins/chr.hpp
new file mode 100644
index 00000000000..3984cb549ae
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/chr.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_BUILTIN_CHR_HPP
+#define PYTHONIC_BUILTIN_CHR_HPP
+
+#include "pythonic/include/builtins/chr.hpp"
+
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+ template <class T>
+ types::str chr(T const &v)
+ {
+ return types::str((char)v);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/complex.hpp b/contrib/python/pythran/pythran/pythonic/builtins/complex.hpp
new file mode 100644
index 00000000000..9629896d943
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/complex.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_BUILTIN_COMPLEX_HPP
+#define PYTHONIC_BUILTIN_COMPLEX_HPP
+
+#include "pythonic/include/builtins/complex.hpp"
+
+#include "pythonic/types/complex.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace functor
+ {
+ inline complex::type complex::operator()(double v0, double v1) const
+ {
+ return {v0, v1};
+ }
+ } // namespace functor
+} // namespace builtins
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/complex/conjugate.hpp b/contrib/python/pythran/pythran/pythonic/builtins/complex/conjugate.hpp
new file mode 100644
index 00000000000..09a1e8468e8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/complex/conjugate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_BUILTIN_COMPLEX_CONJUGATE_HPP
+#define PYTHONIC_BUILTIN_COMPLEX_CONJUGATE_HPP
+
+#include "pythonic/include/builtins/complex/conjugate.hpp"
+#include "pythonic/numpy/conjugate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/dict/clear.hpp b/contrib/python/pythran/pythran/pythonic/builtins/dict/clear.hpp
new file mode 100644
index 00000000000..7efdba91358
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/dict/clear.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_BUILTIN_DICT_CLEAR_HPP
+#define PYTHONIC_BUILTIN_DICT_CLEAR_HPP
+
+#include "pythonic/include/builtins/dict/clear.hpp"
+#include "pythonic/__dispatch__/clear.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/dict/copy.hpp b/contrib/python/pythran/pythran/pythonic/builtins/dict/copy.hpp
new file mode 100644
index 00000000000..06fcbb767d9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/dict/copy.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_BUILTIN_DICT_COPY_HPP
+#define PYTHONIC_BUILTIN_DICT_COPY_HPP
+
+#include "pythonic/include/builtins/dict/copy.hpp"
+#include "pythonic/__dispatch__/copy.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/dict/fromkeys.hpp b/contrib/python/pythran/pythran/pythonic/builtins/dict/fromkeys.hpp
new file mode 100644
index 00000000000..2fb83b6e8e6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/dict/fromkeys.hpp
@@ -0,0 +1,34 @@
+#ifndef PYTHONIC_BUILTIN_DICT_FROMKEYS_HPP
+#define PYTHONIC_BUILTIN_DICT_FROMKEYS_HPP
+
+#include "pythonic/include/builtins/dict/fromkeys.hpp"
+
+#include "pythonic/types/dict.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <type_traits>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace dict
+ {
+
+ template <class Iterable, class V>
+ types::dict<typename std::remove_reference<Iterable>::type::value_type, V>
+ fromkeys(Iterable &&iter, V const &v)
+ {
+ types::dict<typename std::remove_reference<Iterable>::type::value_type,
+ V> D =
+ types::empty_dict(); // Allocate default capacity to dict
+ for (auto const &i : iter)
+ D[i] = v;
+ return D;
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/dict/get.hpp b/contrib/python/pythran/pythran/pythonic/builtins/dict/get.hpp
new file mode 100644
index 00000000000..bcb0f587a0b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/dict/get.hpp
@@ -0,0 +1,39 @@
+#ifndef PYTHONIC_BUILTIN_DICT_GET_HPP
+#define PYTHONIC_BUILTIN_DICT_GET_HPP
+
+#include "pythonic/include/builtins/dict/get.hpp"
+
+#include "pythonic/types/dict.hpp"
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace dict
+ {
+ template <class K, class V, class W, class X>
+ typename __combined<V, X>::type get(types::dict<K, V> const &d, W const &k,
+ X const &default_)
+ {
+ return d.get(k, default_);
+ }
+
+ template <class K, class V, class W>
+ types::none<V> get(types::dict<K, V> const &d, W const &k)
+ {
+ return d.get(k);
+ }
+
+ template <class W, class X>
+ X get(types::empty_dict const &, W const &, X const &default_)
+ {
+ return default_;
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/dict/items.hpp b/contrib/python/pythran/pythran/pythonic/builtins/dict/items.hpp
new file mode 100644
index 00000000000..5bbd6ced2f9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/dict/items.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_BUILTIN_DICT_ITEMS_HPP
+#define PYTHONIC_BUILTIN_DICT_ITEMS_HPP
+
+#include "pythonic/include/builtins/dict/items.hpp"
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/dict.hpp"
+#include "pythonic/include/types/list.hpp"
+
+#include <tuple>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace dict
+ {
+
+ template <class D>
+ auto items(D &&d) -> decltype(std::forward<D>(d).items())
+ {
+ return std::forward<D>(d).items();
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/dict/keys.hpp b/contrib/python/pythran/pythran/pythonic/builtins/dict/keys.hpp
new file mode 100644
index 00000000000..d4dfa271d79
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/dict/keys.hpp
@@ -0,0 +1,30 @@
+#ifndef PYTHONIC_BUILTIN_DICT_KEYS_HPP
+#define PYTHONIC_BUILTIN_DICT_KEYS_HPP
+
+#include "pythonic/include/builtins/dict/keys.hpp"
+
+#include "pythonic/types/dict.hpp"
+#include "pythonic/types/list.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace dict
+ {
+
+ // We need a copy here for lvalue like :
+ // for i in {"a": "b", "c": "d"}.keys():
+ // pass
+ template <class D>
+ auto keys(D &&d) -> decltype(std::forward<D>(d).keys())
+ {
+ return std::forward<D>(d).keys();
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/dict/pop.hpp b/contrib/python/pythran/pythran/pythonic/builtins/dict/pop.hpp
new file mode 100644
index 00000000000..a22e470576e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/dict/pop.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_BUILTIN_DICT_POP_HPP
+#define PYTHONIC_BUILTIN_DICT_POP_HPP
+
+#include "pythonic/include/builtins/dict/pop.hpp"
+#include "pythonic/__dispatch__/pop.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/dict/popitem.hpp b/contrib/python/pythran/pythran/pythonic/builtins/dict/popitem.hpp
new file mode 100644
index 00000000000..e0369befcaa
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/dict/popitem.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_BUILTIN_DICT_POPITEM_HPP
+#define PYTHONIC_BUILTIN_DICT_POPITEM_HPP
+
+#include "pythonic/include/builtins/dict/popitem.hpp"
+
+#include "pythonic/types/dict.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <tuple>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace dict
+ {
+
+ template <class D>
+ auto popitem(D &&d) -> decltype(std::forward<D>(d).popitem())
+ {
+ return std::forward<D>(d).popitem();
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/dict/setdefault.hpp b/contrib/python/pythran/pythran/pythonic/builtins/dict/setdefault.hpp
new file mode 100644
index 00000000000..3f1079897aa
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/dict/setdefault.hpp
@@ -0,0 +1,44 @@
+#ifndef PYTHONIC_BUILTIN_DICT_SETDEFAULT_HPP
+#define PYTHONIC_BUILTIN_DICT_SETDEFAULT_HPP
+
+#include "pythonic/include/builtins/dict/setdefault.hpp"
+
+#include "pythonic/types/dict.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace dict
+ {
+
+ template <class K, class V, class W, class X>
+ V &setdefault(types::dict<K, V> &d, W const &k, X const &default_)
+ {
+ return d.setdefault(k, default_);
+ }
+
+ template <class K, class V, class W>
+ types::none<V> setdefault(types::dict<K, V> &d, W const &k)
+ {
+ return d.get(k);
+ }
+
+ template <class K, class V, class W, class X>
+ V setdefault(types::dict<K, V> &&d, W const &k, X const &default_)
+ {
+ return d.setdefault(k, default_);
+ }
+
+ template <class K, class V, class W>
+ types::none<V> setdefault(types::dict<K, V> &&d, W const &k)
+ {
+ return d.get(k);
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/dict/update.hpp b/contrib/python/pythran/pythran/pythonic/builtins/dict/update.hpp
new file mode 100644
index 00000000000..ffda356efd2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/dict/update.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_BUILTIN_DICT_UPDATE_HPP
+#define PYTHONIC_BUILTIN_DICT_UPDATE_HPP
+
+#include "pythonic/include/builtins/dict/update.hpp"
+#include "pythonic/__dispatch__/update.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/dict/values.hpp b/contrib/python/pythran/pythran/pythonic/builtins/dict/values.hpp
new file mode 100644
index 00000000000..69fd137d3d6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/dict/values.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_BUILTIN_DICT_VALUES_HPP
+#define PYTHONIC_BUILTIN_DICT_VALUES_HPP
+
+#include "pythonic/include/builtins/dict/values.hpp"
+
+#include "pythonic/types/dict.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace dict
+ {
+
+ template <class D>
+ auto values(D &&d) -> decltype(std::forward<D>(d).values())
+ {
+ return std::forward<D>(d).values();
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/divmod.hpp b/contrib/python/pythran/pythran/pythonic/builtins/divmod.hpp
new file mode 100644
index 00000000000..8227d53915b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/divmod.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_BUILTIN_DIVMOD_HPP
+#define PYTHONIC_BUILTIN_DIVMOD_HPP
+
+#include "pythonic/include/builtins/divmod.hpp"
+
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ template <class T0, class T1>
+ auto divmod(T0 const &t0, T1 const &t1) // other types are left over
+ -> decltype(types::make_tuple(t0 / t1, t0 % t1))
+ {
+ return types::make_tuple(t0 / t1, t0 % t1);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/enumerate.hpp b/contrib/python/pythran/pythran/pythonic/builtins/enumerate.hpp
new file mode 100644
index 00000000000..06ed8918459
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/enumerate.hpp
@@ -0,0 +1,117 @@
+#ifndef PYTHONIC_BUILTIN_ENUMERATE_HPP
+#define PYTHONIC_BUILTIN_ENUMERATE_HPP
+
+#include "pythonic/include/builtins/enumerate.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+#include <tuple>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace details
+ {
+ /// enumerate_iterator implementation
+
+ template <class Iterator>
+ enumerate_iterator<Iterator>::enumerate_iterator()
+ {
+ }
+
+ template <class Iterator>
+ enumerate_iterator<Iterator>::enumerate_iterator(Iterator const &iter,
+ long first)
+ : value(first), iter(iter)
+ {
+ }
+
+ template <class Iterator>
+ enumerate_iterator<Iterator> &enumerate_iterator<Iterator>::
+ operator+=(long n)
+ {
+ value += n, iter += n;
+ return *this;
+ }
+
+ // Comparison operators can't use value as end() doesn't have a valid
+ // value content
+ // du to the lake of size information for generator
+ // TODO : We could handle case with && without size if there is a
+ // performances benefits
+ template <class Iterator>
+ bool enumerate_iterator<Iterator>::
+ operator!=(enumerate_iterator<Iterator> const &other) const
+ {
+ return !(*this == other);
+ }
+
+ template <class Iterator>
+ bool enumerate_iterator<Iterator>::
+ operator<(enumerate_iterator const &other) const
+ {
+ return iter < other.iter;
+ }
+
+ template <class Iterator>
+ bool enumerate_iterator<Iterator>::
+ operator==(enumerate_iterator<Iterator> const &other) const
+ {
+ return iter == other.iter;
+ }
+
+ template <class Iterator>
+ long enumerate_iterator<Iterator>::
+ operator-(enumerate_iterator<Iterator> const &other) const
+ {
+ return iter - other.iter;
+ }
+
+ /// details::enumerate implementation
+ template <class Iterable>
+ enumerate<Iterable>::enumerate()
+ {
+ }
+
+ template <class Iterable>
+ enumerate<Iterable>::enumerate(Iterable seq, long first)
+ : Iterable(seq), iterator(Iterable::begin(), first),
+ end_iter(Iterable::end(), -1)
+ {
+ }
+
+ template <class Iterable>
+ typename enumerate<Iterable>::iterator &enumerate<Iterable>::begin()
+ {
+ return *this;
+ }
+
+ template <class Iterable>
+ typename enumerate<Iterable>::iterator const &
+ enumerate<Iterable>::begin() const
+ {
+ return *this;
+ }
+
+ template <class Iterable>
+ typename enumerate<Iterable>::iterator enumerate<Iterable>::end() const
+ {
+ return end_iter;
+ }
+ }
+
+ /// enumerate implementation
+
+ template <class Iterable>
+ details::enumerate<typename std::remove_cv<
+ typename std::remove_reference<Iterable>::type>::type>
+ enumerate(Iterable &&seq, long first)
+ {
+ return {std::forward<Iterable>(seq), first};
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/file.hpp b/contrib/python/pythran/pythran/pythonic/builtins/file.hpp
new file mode 100644
index 00000000000..fef17cbc151
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/file.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_BUILTIN_FILE_HPP
+#define PYTHONIC_BUILTIN_FILE_HPP
+
+#include "pythonic/include/builtins/file.hpp"
+
+#include "pythonic/types/file.hpp"
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace anonymous
+ {
+ types::file file(types::str const &filename, types::str const &strmode)
+ {
+ return {filename, strmode};
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/file/close.hpp b/contrib/python/pythran/pythran/pythonic/builtins/file/close.hpp
new file mode 100644
index 00000000000..29de5f4b627
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/file/close.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_BUILTIN_FILE_CLOSE_HPP
+#define PYTHONIC_BUILTIN_FILE_CLOSE_HPP
+
+#include "pythonic/include/builtins/file/close.hpp"
+
+#include "pythonic/types/file.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ inline void close(types::file &f)
+ {
+ f.close();
+ }
+
+ inline void close(types::file &&f)
+ {
+ f.close();
+ }
+ } // namespace file
+} // namespace builtins
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/file/fileno.hpp b/contrib/python/pythran/pythran/pythonic/builtins/file/fileno.hpp
new file mode 100644
index 00000000000..b167d3ade20
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/file/fileno.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_BUILTIN_FILE_FILENO_HPP
+#define PYTHONIC_BUILTIN_FILE_FILENO_HPP
+
+#include "pythonic/include/builtins/file/fileno.hpp"
+
+#include "pythonic/types/file.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ long fileno(types::file const &f)
+ {
+ return f.fileno();
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/file/flush.hpp b/contrib/python/pythran/pythran/pythonic/builtins/file/flush.hpp
new file mode 100644
index 00000000000..dad4656cfb9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/file/flush.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_BUILTIN_FILE_FLUSH_HPP
+#define PYTHONIC_BUILTIN_FILE_FLUSH_HPP
+
+#include "pythonic/include/builtins/file/flush.hpp"
+
+#include "pythonic/types/file.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ inline void flush(types::file &f)
+ {
+ f.flush();
+ }
+
+ inline void flush(types::file &&f)
+ {
+ f.flush();
+ }
+ } // namespace file
+} // namespace builtins
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/file/isatty.hpp b/contrib/python/pythran/pythran/pythonic/builtins/file/isatty.hpp
new file mode 100644
index 00000000000..b8e0216003e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/file/isatty.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_BUILTIN_FILE_ISATTY_HPP
+#define PYTHONIC_BUILTIN_FILE_ISATTY_HPP
+
+#include "pythonic/include/builtins/file/isatty.hpp"
+
+#include "pythonic/types/file.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ bool isatty(types::file const &f)
+ {
+ return f.isatty();
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/file/next.hpp b/contrib/python/pythran/pythran/pythonic/builtins/file/next.hpp
new file mode 100644
index 00000000000..f1ae5fbafe5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/file/next.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_BUILTIN_FILE_NEXT_HPP
+#define PYTHONIC_BUILTIN_FILE_NEXT_HPP
+
+#include "pythonic/include/builtins/file/next.hpp"
+#include "pythonic/__dispatch__/next.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/file/read.hpp b/contrib/python/pythran/pythran/pythonic/builtins/file/read.hpp
new file mode 100644
index 00000000000..dde8e2ad44e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/file/read.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_BUILTIN_FILE_READ_HPP
+#define PYTHONIC_BUILTIN_FILE_READ_HPP
+
+#include "pythonic/include/builtins/file/read.hpp"
+
+#include "pythonic/types/file.hpp"
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ inline types::str read(types::file &f, long size)
+ {
+ return f.read(size);
+ }
+ inline types::str read(types::file &&f, long size)
+ {
+ return f.read(size);
+ }
+ } // namespace file
+} // namespace builtins
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/file/readline.hpp b/contrib/python/pythran/pythran/pythonic/builtins/file/readline.hpp
new file mode 100644
index 00000000000..565c296fba3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/file/readline.hpp
@@ -0,0 +1,30 @@
+#ifndef PYTHONIC_BUILTIN_FILE_READLINE_HPP
+#define PYTHONIC_BUILTIN_FILE_READLINE_HPP
+
+#include "pythonic/include/builtins/file/readline.hpp"
+
+#include "pythonic/types/file.hpp"
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ inline types::str readline(types::file &f, long size)
+ {
+ return size < 0 ? f.readline() : f.readline(size);
+ }
+
+ inline types::str readline(types::file &&f, long size)
+ {
+ return size < 0 ? f.readline() : f.readline(size);
+ }
+ } // namespace file
+} // namespace builtins
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/file/readlines.hpp b/contrib/python/pythran/pythran/pythonic/builtins/file/readlines.hpp
new file mode 100644
index 00000000000..5bea169b08a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/file/readlines.hpp
@@ -0,0 +1,33 @@
+#ifndef PYTHONIC_BUILTIN_FILE_READLINES_HPP
+#define PYTHONIC_BUILTIN_FILE_READLINES_HPP
+
+#include "pythonic/include/builtins/file/readlines.hpp"
+
+#include "pythonic/types/file.hpp"
+#include "pythonic/types/list.hpp"
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ template <class F>
+ types::list<types::str> readlines(F &&f)
+ {
+ return f.readlines();
+ }
+
+ template <class F>
+ types::list<types::str> readlines(F &&f, long sizehint)
+ {
+ return f.readlines(sizehint);
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/file/seek.hpp b/contrib/python/pythran/pythran/pythonic/builtins/file/seek.hpp
new file mode 100644
index 00000000000..93beb0d403f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/file/seek.hpp
@@ -0,0 +1,39 @@
+#ifndef PYTHONIC_BUILTIN_FILE_SEEK_HPP
+#define PYTHONIC_BUILTIN_FILE_SEEK_HPP
+
+#include "pythonic/include/builtins/file/seek.hpp"
+
+#include "pythonic/types/file.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ inline void seek(types::file &f, long offset)
+ {
+ f.seek(offset);
+ }
+
+ inline void seek(types::file &&f, long offset)
+ {
+ // Nothing have to be done as it is a lvalue
+ }
+
+ inline void seek(types::file &f, long offset, long whence)
+ {
+ f.seek(offset, whence);
+ }
+
+ inline void seek(types::file &&f, long offset, long whence)
+ {
+ // Nothing have to be done as it is a lvalue
+ }
+ } // namespace file
+} // namespace builtins
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/file/tell.hpp b/contrib/python/pythran/pythran/pythonic/builtins/file/tell.hpp
new file mode 100644
index 00000000000..dc5fbabe218
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/file/tell.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_BUILTIN_FILE_TELL_HPP
+#define PYTHONIC_BUILTIN_FILE_TELL_HPP
+
+#include "pythonic/include/builtins/file/tell.hpp"
+
+#include "pythonic/types/file.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ long tell(types::file const &f)
+ {
+ return f.tell();
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/file/truncate.hpp b/contrib/python/pythran/pythran/pythonic/builtins/file/truncate.hpp
new file mode 100644
index 00000000000..ad605e2477e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/file/truncate.hpp
@@ -0,0 +1,39 @@
+#ifndef PYTHONIC_BUILTIN_FILE_TRUNCATE_HPP
+#define PYTHONIC_BUILTIN_FILE_TRUNCATE_HPP
+
+#include "pythonic/include/builtins/file/truncate.hpp"
+
+#include "pythonic/types/file.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ inline void truncate(types::file &f)
+ {
+ f.truncate();
+ }
+
+ inline void truncate(types::file &&f)
+ {
+ f.truncate();
+ }
+
+ inline void truncate(types::file &f, long size)
+ {
+ f.truncate(size);
+ }
+
+ inline void truncate(types::file &&f, long size)
+ {
+ f.truncate(size);
+ }
+ } // namespace file
+} // namespace builtins
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/file/write.hpp b/contrib/python/pythran/pythran/pythonic/builtins/file/write.hpp
new file mode 100644
index 00000000000..205440ef64e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/file/write.hpp
@@ -0,0 +1,30 @@
+#ifndef PYTHONIC_BUILTIN_FILE_WRITE_HPP
+#define PYTHONIC_BUILTIN_FILE_WRITE_HPP
+
+#include "pythonic/include/builtins/file/write.hpp"
+
+#include "pythonic/types/file.hpp"
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ inline long write(types::file &f, types::str const &str)
+ {
+ return f.write(str);
+ }
+
+ inline long write(types::file &&f, types::str const &str)
+ {
+ return f.write(str);
+ }
+ } // namespace file
+} // namespace builtins
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/file/writelines.hpp b/contrib/python/pythran/pythran/pythonic/builtins/file/writelines.hpp
new file mode 100644
index 00000000000..6859de2d44e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/file/writelines.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_BUILTIN_FILE_WRITELINES_HPP
+#define PYTHONIC_BUILTIN_FILE_WRITELINES_HPP
+
+#include "pythonic/include/builtins/file/writelines.hpp"
+
+#include "pythonic/types/file.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ template <class F, class T>
+ void writelines(F &&f, T const &sequence)
+ {
+ f.writelines(sequence);
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/filter.hpp b/contrib/python/pythran/pythran/pythonic/builtins/filter.hpp
new file mode 100644
index 00000000000..8708be72122
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/filter.hpp
@@ -0,0 +1,130 @@
+#ifndef PYTHONIC_BUILTIN_FILTER_HPP
+#define PYTHONIC_BUILTIN_FILTER_HPP
+
+#include "pythonic/include/builtins/filter.hpp"
+
+#include "pythonic/itertools/common.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/iterator.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+ namespace details
+ {
+ template <typename Operator, typename List0>
+ bool filter_iterator<Operator, List0>::test_filter(std::false_type)
+ {
+ return op(*iter);
+ }
+
+ template <typename Operator, typename List0>
+ bool filter_iterator<Operator, List0>::test_filter(std::true_type)
+ {
+ return *iter;
+ }
+
+ template <typename Operator, typename List0>
+ filter_iterator<Operator, List0>::filter_iterator(Operator _op, List0 &_seq)
+ : op(_op), iter(_seq.begin()), iter_end(_seq.end())
+ {
+ if (iter != iter_end &&
+ !test_filter(std::is_same<types::none_type, Operator>()))
+ next_value();
+ }
+
+ template <typename Operator, typename List0>
+ filter_iterator<Operator, List0>::filter_iterator(itertools::npos,
+ Operator _op, List0 &_seq)
+ : op(_op), iter(_seq.end()), iter_end(_seq.end())
+ {
+ }
+
+ template <typename Operator, typename List0>
+ typename List0::value_type
+ filter_iterator<Operator, List0>::operator*() const
+ {
+ return *iter;
+ }
+
+ template <typename Operator, typename List0>
+ filter_iterator<Operator, List0> &
+ filter_iterator<Operator, List0>::operator++()
+ {
+ next_value();
+ return *this;
+ }
+
+ template <typename Operator, typename List0>
+ void filter_iterator<Operator, List0>::next_value()
+ {
+ while (++iter != iter_end) {
+ if (test_filter(std::is_same<types::none_type, Operator>()))
+ return;
+ }
+ }
+
+ template <typename Operator, typename List0>
+ bool filter_iterator<Operator, List0>::operator==(
+ filter_iterator const &other) const
+ {
+ return !(iter != other.iter);
+ }
+
+ template <typename Operator, typename List0>
+ bool filter_iterator<Operator, List0>::operator!=(
+ filter_iterator const &other) const
+ {
+ return iter != other.iter;
+ }
+
+ template <typename Operator, typename List0>
+ bool filter_iterator<Operator, List0>::operator<(
+ filter_iterator const &other) const
+ {
+ return iter != other.iter;
+ }
+
+ template <typename Operator, typename List0>
+ filter<Operator, List0>::filter(Operator _op, List0 const &_seq)
+ : utils::iterator_reminder<false, List0>(_seq),
+ iterator(_op, this->values),
+ end_iter(itertools::npos(), _op, this->values)
+ {
+ }
+
+ template <typename Operator, typename List0>
+ typename filter<Operator, List0>::iterator &filter<Operator, List0>::begin()
+ {
+ return *this;
+ }
+
+ template <typename Operator, typename List0>
+ typename filter<Operator, List0>::iterator const &
+ filter<Operator, List0>::begin() const
+ {
+ return *this;
+ }
+
+ template <typename Operator, typename List0>
+ typename filter<Operator, List0>::iterator const &
+ filter<Operator, List0>::end() const
+ {
+ return end_iter;
+ }
+ } // namespace details
+
+ template <typename Operator, typename List0>
+ details::filter<typename std::remove_cv<
+ typename std::remove_reference<Operator>::type>::type,
+ typename std::remove_cv<
+ typename std::remove_reference<List0>::type>::type>
+ filter(Operator &&_op, List0 &&_seq)
+ {
+ return {std::forward<Operator>(_op), std::forward<List0>(_seq)};
+ }
+} // namespace builtins
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/float_/is_integer.hpp b/contrib/python/pythran/pythran/pythonic/builtins/float_/is_integer.hpp
new file mode 100644
index 00000000000..5ffccf83838
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/float_/is_integer.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_BUILTIN_FLOAT_ISINTEGER_HPP
+#define PYTHONIC_BUILTIN_FLOAT_ISINTEGER_HPP
+
+#include "pythonic/include/builtins/float_/is_integer.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace float_
+ {
+
+ bool is_integer(double d)
+ {
+ return std::trunc(d) == d;
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/hex.hpp b/contrib/python/pythran/pythran/pythonic/builtins/hex.hpp
new file mode 100644
index 00000000000..3ab0221f0bd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/hex.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_BUILTIN_HEX_HPP
+#define PYTHONIC_BUILTIN_HEX_HPP
+
+#include "pythonic/include/builtins/hex.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/str.hpp"
+
+#include <sstream>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ template <class T>
+ types::str hex(T const &v)
+ {
+ std::ostringstream oss;
+ oss << "0x" << std::hex << v;
+ return oss.str();
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/isinstance.hpp b/contrib/python/pythran/pythran/pythonic/builtins/isinstance.hpp
new file mode 100644
index 00000000000..0c63b65645e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/isinstance.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_BUILTIN_ISINSTANCE_HPP
+#define PYTHONIC_BUILTIN_ISINSTANCE_HPP
+
+#include "pythonic/include/builtins/isinstance.hpp"
+#include "pythonic/include/builtins/pythran/is_none.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/iter.hpp b/contrib/python/pythran/pythran/pythonic/builtins/iter.hpp
new file mode 100644
index 00000000000..dc54d242a56
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/iter.hpp
@@ -0,0 +1,61 @@
+#ifndef PYTHONIC_BUILTIN_ITER_HPP
+#define PYTHONIC_BUILTIN_ITER_HPP
+
+#include "pythonic/include/builtins/iter.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace details
+ {
+ /// details iter implementation
+
+ template <class T>
+ iter<T>::iter()
+ {
+ }
+
+ // FIXME : There is a dangling reference as data.begin() is ! the one
+ // from data "saved" in the "iter" struct
+ template <class T>
+ iter<T>::iter(T data)
+ : iterator(data.begin()), _end(data.end()), data(data)
+ {
+ }
+
+ template <class T>
+ typename iter<T>::iterator &iter<T>::begin()
+ {
+ return *this;
+ }
+
+ template <class T>
+ typename iter<T>::iterator const &iter<T>::begin() const
+ {
+ return *this;
+ }
+
+ template <class T>
+ typename iter<T>::iterator const &iter<T>::end() const
+ {
+ return _end;
+ }
+ }
+
+ /// iter implementation
+
+ template <class T>
+ details::iter<
+ typename std::remove_cv<typename std::remove_reference<T>::type>::type>
+ iter(T &&t)
+ {
+ return {std::forward<T>(t)};
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/list/count.hpp b/contrib/python/pythran/pythran/pythonic/builtins/list/count.hpp
new file mode 100644
index 00000000000..e43223ea9dd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/list/count.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_BUILTIN_LIST_COUNT_HPP
+#define PYTHONIC_BUILTIN_LIST_COUNT_HPP
+
+#include "pythonic/include/builtins/list/count.hpp"
+#include "pythonic/__dispatch__/count.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/list/extend.hpp b/contrib/python/pythran/pythran/pythonic/builtins/list/extend.hpp
new file mode 100644
index 00000000000..273f4cf80a0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/list/extend.hpp
@@ -0,0 +1,39 @@
+#ifndef PYTHONIC_BUILTIN_LIST_EXTEND_HPP
+#define PYTHONIC_BUILTIN_LIST_EXTEND_HPP
+
+#include "pythonic/include/builtins/list/extend.hpp"
+
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/types/list.hpp"
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace list
+ {
+ template <class T0, class T1>
+ typename std::enable_if<
+ !std::is_same<typename std::decay<T0>::type, types::empty_list>::value,
+ types::none_type>::type
+ extend(T0 &&seq, T1 const &add)
+ {
+ std::forward<T0>(seq) += add;
+ return {};
+ }
+
+ template <class T0, class T1>
+ typename std::enable_if<
+ std::is_same<typename std::decay<T0>::type, types::empty_list>::value,
+ types::none_type>::type
+ extend(T0 &&seq, T1 const &add)
+ {
+ return {};
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/list/insert.hpp b/contrib/python/pythran/pythran/pythonic/builtins/list/insert.hpp
new file mode 100644
index 00000000000..123a0178848
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/list/insert.hpp
@@ -0,0 +1,33 @@
+#ifndef PYTHONIC_BUILTIN_LIST_INSERT_HPP
+#define PYTHONIC_BUILTIN_LIST_INSERT_HPP
+
+#include "pythonic/include/builtins/list/insert.hpp"
+
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/types/list.hpp"
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace list
+ {
+
+ // TODO : range_analysis may be use to have a "fast insert" function.
+ template <class T, class F>
+ types::none_type insert(types::list<T> &seq, long n, F &&value)
+ {
+ n = n % (1 + seq.size()); // +1 because we want to be able to insert at
+ // the end of seq
+ if (n < 0)
+ n += seq.size();
+ seq.insert(n, std::forward<F>(value));
+ return builtins::None;
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/list/pop.hpp b/contrib/python/pythran/pythran/pythonic/builtins/list/pop.hpp
new file mode 100644
index 00000000000..37cd6fecb99
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/list/pop.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_BUILTIN_LIST_POP_HPP
+#define PYTHONIC_BUILTIN_LIST_POP_HPP
+
+#include "pythonic/include/builtins/list/pop.hpp"
+#include "pythonic/__dispatch__/pop.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/list/remove.hpp b/contrib/python/pythran/pythran/pythonic/builtins/list/remove.hpp
new file mode 100644
index 00000000000..1d655470655
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/list/remove.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_BUILTIN_LIST_REMOVE_HPP
+#define PYTHONIC_BUILTIN_LIST_REMOVE_HPP
+
+#include "pythonic/include/builtins/list/remove.hpp"
+#include "pythonic/__dispatch__/remove.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/list/reverse.hpp b/contrib/python/pythran/pythran/pythonic/builtins/list/reverse.hpp
new file mode 100644
index 00000000000..2948d3f24b2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/list/reverse.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_BUILTIN_LIST_REVERSE_HPP
+#define PYTHONIC_BUILTIN_LIST_REVERSE_HPP
+
+#include "pythonic/include/builtins/list/reverse.hpp"
+
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/types/list.hpp"
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace list
+ {
+
+ template <class T>
+ types::none_type reverse(types::list<T> &seq)
+ {
+ std::reverse(seq.begin(), seq.end());
+ return builtins::None;
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/list/sort.hpp b/contrib/python/pythran/pythran/pythonic/builtins/list/sort.hpp
new file mode 100644
index 00000000000..365de6505d9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/list/sort.hpp
@@ -0,0 +1,38 @@
+#ifndef PYTHONIC_BUILTIN_LIST_SORT_HPP
+#define PYTHONIC_BUILTIN_LIST_SORT_HPP
+
+#include "pythonic/include/builtins/list/sort.hpp"
+
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/types/list.hpp"
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/pdqsort.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace list
+ {
+
+ template <class T>
+ types::none_type sort(types::list<T> &seq)
+ {
+ pdqsort(seq.begin(), seq.end());
+ return builtins::None;
+ }
+
+ template <class T, class K>
+ types::none_type sort(types::list<T> &seq, K key)
+ {
+ pdqsort(seq.begin(), seq.end(), [&key](T const &self, T const &other) {
+ return key(self) < key(other);
+ });
+ return builtins::None;
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/map.hpp b/contrib/python/pythran/pythran/pythonic/builtins/map.hpp
new file mode 100644
index 00000000000..fde24f3d3af
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/map.hpp
@@ -0,0 +1,223 @@
+#ifndef PYTHONIC_BUILTIN_MAP_HPP
+#define PYTHONIC_BUILTIN_MAP_HPP
+
+#include "pythonic/include/builtins/map.hpp"
+
+#include "pythonic/itertools/common.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/fwd.hpp"
+#include "pythonic/utils/int_.hpp"
+#include "pythonic/utils/iterator.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/seq.hpp"
+
+#include <iterator>
+#include <tuple>
+#include <type_traits>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+ namespace details
+ {
+
+ template <typename Operator, typename... Iters>
+ template <size_t... I>
+ map_iterator<Operator, Iters...>::map_iterator(Operator const &op,
+ std::tuple<Iters...> &_iters,
+ utils::index_sequence<I...>)
+ : it(std::get<I>(_iters).begin()...), _op(op)
+ {
+ }
+
+ template <typename Operator, typename... Iters>
+ template <size_t... I>
+ map_iterator<Operator, Iters...>::map_iterator(itertools::npos,
+ Operator const &op,
+ std::tuple<Iters...> &_iters,
+ utils::index_sequence<I...>)
+ : it(std::get<I>(_iters).end()...), _op(op)
+ {
+ }
+
+ template <typename Operator, typename... Iters>
+ template <size_t... I>
+ typename map_res<Operator, Iters...>::type
+ map_iterator<Operator, Iters...>::get_value(utils::index_sequence<I...>,
+ std::false_type) const
+ {
+ return _op(*std::get<I>(it)...);
+ }
+
+ template <typename Operator, typename... Iters>
+ template <size_t... I>
+ typename map_res<Operator, Iters...>::type
+ map_iterator<Operator, Iters...>::get_value(utils::index_sequence<I...>,
+ std::true_type) const
+ {
+ return types::make_tuple(*std::get<I>(it)...);
+ }
+
+ template <typename Operator, typename... Iters>
+ typename map_res<Operator, Iters...>::type
+ map_iterator<Operator, Iters...>::
+ operator*() const
+ {
+ return get_value(utils::make_index_sequence<sizeof...(Iters)>{},
+ std::is_same<Operator, types::none_type>());
+ }
+
+ template <typename Operator, typename... Iters>
+ template <size_t... I>
+ void map_iterator<Operator, Iters...>::next(utils::index_sequence<I...>)
+ {
+ utils::fwd(++std::get<I>(it)...);
+ }
+
+ template <typename Operator, typename... Iters>
+ map_iterator<Operator, Iters...> &map_iterator<Operator, Iters...>::
+ operator++()
+ {
+ next(utils::make_index_sequence<sizeof...(Iters)>{});
+ return *this;
+ }
+
+ template <typename Operator, typename... Iters>
+ template <size_t I>
+ void map_iterator<Operator, Iters...>::advance(long i, utils::int_<I>)
+ {
+ std::get<I>(it) += i;
+ advance(i, utils::int_<I - 1>());
+ }
+
+ template <typename Operator, typename... Iters>
+ void map_iterator<Operator, Iters...>::advance(long i, utils::int_<0>)
+ {
+ std::get<0>(it) += i;
+ }
+
+ template <typename Operator, typename... Iters>
+ map_iterator<Operator, Iters...> &map_iterator<Operator, Iters...>::
+ operator+=(long i)
+ {
+ advance(i, utils::int_<sizeof...(Iters)-1>());
+ return *this;
+ }
+
+ template <typename Operator, typename... Iters>
+ map_iterator<Operator, Iters...> map_iterator<Operator, Iters...>::
+ operator+(long i) const
+ {
+ map_iterator<Operator, Iters...> other(*this);
+ other += i;
+ return other;
+ }
+
+ template <typename Operator, typename... Iters>
+ template <size_t N>
+ bool map_iterator<Operator, Iters...>::equal(
+ map_iterator<Operator, Iters...> const &other, utils::int_<N>) const
+ {
+ return std::get<N>(other.it) == std::get<N>(it) ||
+ equal(other, utils::int_<N - 1>());
+ }
+
+ template <typename Operator, typename... Iters>
+ bool map_iterator<Operator, Iters...>::equal(
+ map_iterator<Operator, Iters...> const &other, utils::int_<0>) const
+ {
+ return std::get<0>(other.it) == std::get<0>(it);
+ }
+
+ template <typename Operator, typename... Iters>
+ bool map_iterator<Operator, Iters...>::
+ operator==(map_iterator<Operator, Iters...> const &other) const
+ {
+ return equal(other, utils::int_<sizeof...(Iters)-1>());
+ }
+
+ template <typename Operator, typename... Iters>
+ bool map_iterator<Operator, Iters...>::
+ operator!=(map_iterator<Operator, Iters...> const &other) const
+ {
+ return !(*this == other);
+ }
+
+ template <typename Operator, typename... Iters>
+ bool map_iterator<Operator, Iters...>::
+ operator<(map_iterator<Operator, Iters...> const &other) const
+ {
+ return !(*this == other);
+ }
+
+ template <typename Operator, typename... Iters>
+ template <size_t N>
+ long map_iterator<Operator, Iters...>::min_len(
+ map_iterator<Operator, Iters...> const &other, utils::int_<N>) const
+ {
+ return std::min((long)(std::get<N>(it) - std::get<N>(other.it)),
+ min_len(other, utils::int_<N - 1>()));
+ }
+
+ template <typename Operator, typename... Iters>
+ long map_iterator<Operator, Iters...>::min_len(
+ map_iterator<Operator, Iters...> const &other, utils::int_<0>) const
+ {
+ return std::get<0>(it) - std::get<0>(other.it);
+ }
+
+ template <typename Operator, typename... Iters>
+ long map_iterator<Operator, Iters...>::
+ operator-(map_iterator<Operator, Iters...> const &other) const
+ {
+ return min_len(other, utils::int_<sizeof...(Iters)-1>());
+ }
+
+ template <typename Operator, typename... Iters>
+ template <class... Types>
+ map<Operator, Iters...>::map(Operator const &_op, Types &&... _iters)
+ : utils::iterator_reminder<true, Iters...>(
+ std::forward<Types>(_iters)...),
+ map_iterator<Operator, Iters...>(
+ _op, this->values,
+ utils::make_index_sequence<sizeof...(Iters)>{}),
+ end_iter(itertools::npos(), _op, this->values,
+ utils::make_index_sequence<sizeof...(Iters)>{})
+ {
+ }
+
+ template <typename Operator, typename... Iters>
+ typename map<Operator, Iters...>::iterator &map<Operator, Iters...>::begin()
+ {
+ return *this;
+ }
+
+ template <typename Operator, typename... Iters>
+ typename map<Operator, Iters...>::iterator const &
+ map<Operator, Iters...>::begin() const
+ {
+ return *this;
+ }
+
+ template <typename Operator, typename... Iters>
+ typename map<Operator, Iters...>::iterator const &
+ map<Operator, Iters...>::end() const
+ {
+ return end_iter;
+ }
+ }
+
+ template <typename Operator, typename... Iter>
+ auto map(Operator &&_op, Iter &&... iters) -> details::map<
+ typename std::remove_cv<
+ typename std::remove_reference<Operator>::type>::type,
+ typename types::iterator<typename std::remove_cv<
+ typename std::remove_reference<Iter>::type>::type>::type...>
+ {
+ return {std::forward<Operator>(_op), std::forward<Iter>(iters)...};
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/next.hpp b/contrib/python/pythran/pythran/pythonic/builtins/next.hpp
new file mode 100644
index 00000000000..afecc8b2d53
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/next.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_BUILTIN_NEXT_HPP
+#define PYTHONIC_BUILTIN_NEXT_HPP
+
+#include "pythonic/include/builtins/next.hpp"
+
+#include "pythonic/builtins/StopIteration.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <utility>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ template <class T>
+ auto next(T &&y) -> decltype(*y)
+ {
+ if ((decltype(y.begin()) &)y != y.end()) {
+ auto tmp = *y;
+ ++y;
+ return tmp;
+ } else
+ throw types::StopIteration();
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/oct.hpp b/contrib/python/pythran/pythran/pythonic/builtins/oct.hpp
new file mode 100644
index 00000000000..ec4e483429f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/oct.hpp
@@ -0,0 +1,32 @@
+#ifndef PYTHONIC_BUILTIN_OCT_HPP
+#define PYTHONIC_BUILTIN_OCT_HPP
+
+#include "pythonic/include/builtins/oct.hpp"
+
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <sstream>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ template <class T>
+ types::str oct(T const &v)
+ {
+ std::ostringstream oss;
+ oss <<
+#if defined(__PYTHRAN__) && __PYTHRAN__ == 3
+ "0o"
+#else
+ '0'
+#endif
+ << std::oct << v;
+ return oss.str();
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/open.hpp b/contrib/python/pythran/pythran/pythonic/builtins/open.hpp
new file mode 100644
index 00000000000..6128c3a36cc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/open.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_BUILTIN_OPEN_HPP
+#define PYTHONIC_BUILTIN_OPEN_HPP
+
+#include "pythonic/include/builtins/open.hpp"
+
+#include "pythonic/types/file.hpp"
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ types::file open(types::str const &filename, types::str const &strmode)
+ {
+ return {filename, strmode};
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/ord.hpp b/contrib/python/pythran/pythran/pythonic/builtins/ord.hpp
new file mode 100644
index 00000000000..07a362bf3ce
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/ord.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_BUILTIN_ORD_HPP
+#define PYTHONIC_BUILTIN_ORD_HPP
+
+#include "pythonic/include/builtins/ord.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ long ord(types::str const &v)
+ {
+ if (v.size() != 1)
+ throw types::TypeError(
+ "ord() expected a character, but string of length " +
+ std::to_string(v.size()) + " found");
+ return (long)v.chars()[0];
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/print.hpp b/contrib/python/pythran/pythran/pythonic/builtins/print.hpp
new file mode 100644
index 00000000000..4b9ba7b0072
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/print.hpp
@@ -0,0 +1,58 @@
+#ifndef PYTHONIC_BUILTIN_PRINT_HPP
+#define PYTHONIC_BUILTIN_PRINT_HPP
+
+#include "pythonic/include/builtins/print.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <iostream>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace details
+ {
+ template <class T>
+ std::ostream &print(std::ostream &os, T const &t)
+ {
+ return os << t;
+ }
+
+ inline std::ostream &print(std::ostream &os, bool const &t)
+ {
+ static char const repr[2][6] = {"False", "True\0"};
+ return os << repr[t];
+ }
+ } // namespace details
+
+ inline void print_nonl()
+ {
+ }
+
+ template <typename T, typename... Types>
+ void print_nonl(T const &value, Types const &...values)
+ {
+ details::print(std::cout, value);
+ if (sizeof...(Types) > 0)
+ std::cout << ' ';
+ print_nonl(values...);
+ }
+
+ inline void print()
+ {
+ std::cout << std::endl;
+ }
+
+ template <typename T, typename... Types>
+ void print(T const &value, Types const &...values)
+ {
+ details::print(std::cout, value);
+ if (sizeof...(values) > 0)
+ std::cout << ' ';
+ print(values...);
+ }
+} // namespace builtins
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/pythran/StaticIfBreak.hpp b/contrib/python/pythran/pythran/pythonic/builtins/pythran/StaticIfBreak.hpp
new file mode 100644
index 00000000000..5086bd6d105
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/pythran/StaticIfBreak.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_BUILTIN_PYTHRAN_STATICIFBREAK_HPP
+#define PYTHONIC_BUILTIN_PYTHRAN_STATICIFBREAK_HPP
+
+#include "pythonic/include/builtins/pythran/StaticIfBreak.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/static_if.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace pythran
+ {
+ template <class T>
+ types::StaticIfBreak<T> StaticIfBreak(T const &arg)
+ {
+ return {arg};
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/pythran/StaticIfCont.hpp b/contrib/python/pythran/pythran/pythonic/builtins/pythran/StaticIfCont.hpp
new file mode 100644
index 00000000000..12b144b7c07
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/pythran/StaticIfCont.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_BUILTIN_PYTHRAN_STATICIFCONT_HPP
+#define PYTHONIC_BUILTIN_PYTHRAN_STATICIFCONT_HPP
+
+#include "pythonic/include/builtins/pythran/StaticIfCont.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/static_if.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace pythran
+ {
+ template <class T>
+ types::StaticIfCont<T> StaticIfCont(T const &arg)
+ {
+ return {arg};
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/pythran/StaticIfNoReturn.hpp b/contrib/python/pythran/pythran/pythonic/builtins/pythran/StaticIfNoReturn.hpp
new file mode 100644
index 00000000000..d7bb508b993
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/pythran/StaticIfNoReturn.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_BUILTIN_PYTHRAN_STATICIFNORETURN_HPP
+#define PYTHONIC_BUILTIN_PYTHRAN_STATICIFNORETURN_HPP
+
+#include "pythonic/include/builtins/pythran/StaticIfNoReturn.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/static_if.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace pythran
+ {
+ template <class T>
+ types::StaticIfNoReturn<T> StaticIfNoReturn(T const &arg)
+ {
+ return {arg};
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/pythran/StaticIfReturn.hpp b/contrib/python/pythran/pythran/pythonic/builtins/pythran/StaticIfReturn.hpp
new file mode 100644
index 00000000000..b0dd350d0b9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/pythran/StaticIfReturn.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_BUILTIN_PYTHRAN_STATICIFRETURN_HPP
+#define PYTHONIC_BUILTIN_PYTHRAN_STATICIFRETURN_HPP
+
+#include "pythonic/include/builtins/pythran/StaticIfReturn.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/static_if.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+ namespace pythran
+ {
+
+ template <class T>
+ types::StaticIfReturn<T> StaticIfReturn(T const &arg)
+ {
+ return {arg};
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/pythran/is_none.hpp b/contrib/python/pythran/pythran/pythonic/builtins/pythran/is_none.hpp
new file mode 100644
index 00000000000..084170ff626
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/pythran/is_none.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_BUILTIN_PYTHRAN_IS_NONE_HPP
+#define PYTHONIC_BUILTIN_PYTHRAN_IS_NONE_HPP
+
+#include "pythonic/include/builtins/pythran/is_none.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/NoneType.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace pythran
+ {
+ }
+}
+
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/pythran/kwonly.hpp b/contrib/python/pythran/pythran/pythonic/builtins/pythran/kwonly.hpp
new file mode 100644
index 00000000000..c1ce88731a6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/pythran/kwonly.hpp
@@ -0,0 +1,4 @@
+#ifndef PYTHONIC_BUILTIN_PYTHRAN_KWONLY_HPP
+#define PYTHONIC_BUILTIN_PYTHRAN_KWONLY_HPP
+#include "pythonic/include/builtins/pythran/kwonly.hpp"
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/pythran/len_set.hpp b/contrib/python/pythran/pythran/pythonic/builtins/pythran/len_set.hpp
new file mode 100644
index 00000000000..6b24e17e507
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/pythran/len_set.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_BUILTIN_PYTHRAN_LEN_SET_HPP
+#define PYTHONIC_BUILTIN_PYTHRAN_LEN_SET_HPP
+
+#include "pythonic/include/builtins/pythran/len_set.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+#include <set>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace pythran
+ {
+
+ template <class Iterable>
+ long len_set(Iterable const &s)
+ {
+ return std::set<typename std::iterator_traits<
+ typename Iterable::iterator>::value_type>(s.begin(), s.end()).size();
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/pythran/or_.hpp b/contrib/python/pythran/pythran/pythonic/builtins/pythran/or_.hpp
new file mode 100644
index 00000000000..08cbeda5463
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/pythran/or_.hpp
@@ -0,0 +1,30 @@
+#ifndef PYTHONIC_BUILTIN_PYTHRAN_OR_HPP
+#define PYTHONIC_BUILTIN_PYTHRAN_OR_HPP
+
+#include "pythonic/include/builtins/pythran/or_.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/combined.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace pythran
+ {
+
+ template <class T0, class T1>
+ types::lazy_combined_t<T0, T1> or_(T0 &&v0, T1 &&v1)
+ {
+ auto &&val0 = std::forward<T0>(v0)();
+ if (val0)
+ return (types::lazy_combined_t<T0, T1>)val0;
+ else
+ return (types::lazy_combined_t<T0, T1>)std::forward<T1>(v1)();
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/pythran/static_if.hpp b/contrib/python/pythran/pythran/pythonic/builtins/pythran/static_if.hpp
new file mode 100644
index 00000000000..cd7e395b843
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/pythran/static_if.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_BUILTIN_PYTHRAN_STATIC_IF_HPP
+#define PYTHONIC_BUILTIN_PYTHRAN_STATIC_IF_HPP
+
+#include "pythonic/include/builtins/pythran/static_if.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/builtins/pythran/is_none.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace pythran
+ {
+
+ template <class T, class F0, class F1>
+ auto static_if(T const &cond, F0 f0, F1 f1)
+ -> decltype(details::static_if<T>{cond}(f0, f1))
+ {
+ return details::static_if<T>{cond}(f0, f1);
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/pythran/static_list.hpp b/contrib/python/pythran/pythran/pythonic/builtins/pythran/static_list.hpp
new file mode 100644
index 00000000000..ee84ae35fcc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/pythran/static_list.hpp
@@ -0,0 +1,42 @@
+#ifndef PYTHONIC_BUILTIN_PYTHRAN_STATIC_LIST_HPP
+#define PYTHONIC_BUILTIN_PYTHRAN_STATIC_LIST_HPP
+
+#include "pythonic/include/builtins/pythran/static_list.hpp"
+#include "pythonic/builtins/list.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace pythran
+ {
+ template <class T, size_t N>
+ types::static_list<T, N> static_list(types::array<T, N> const &other)
+ {
+ return other.template to_array<types::list_version>();
+ }
+ template <class T, size_t N>
+ types::static_list<T, N> static_list(types::array<T, N> &other)
+ {
+ return other.template to_array<types::list_version>();
+ }
+ template <class T, size_t N>
+ types::static_list<T, N> static_list(types::array<T, N> &&other)
+ {
+ return other.template to_array<types::list_version>();
+ }
+
+ template <class T>
+ auto static_list(T &&other)
+ -> decltype(pythonic::builtins::functor::list{}(std::forward<T>(other)))
+ {
+ return pythonic::builtins::functor::list{}(std::forward<T>(other));
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/reduce.hpp b/contrib/python/pythran/pythran/pythonic/builtins/reduce.hpp
new file mode 100644
index 00000000000..e2fb2569a99
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/reduce.hpp
@@ -0,0 +1,46 @@
+#ifndef PYTHONIC_BUILTIN_REDUCE_HPP
+#define PYTHONIC_BUILTIN_REDUCE_HPP
+
+#include "pythonic/include/builtins/reduce.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+#include <numeric>
+#include <utility>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ template <class Iterable, class Operator>
+ auto reduce(Operator op, Iterable s)
+ -> decltype(op(std::declval<typename std::iterator_traits<
+ typename Iterable::iterator>::value_type>(),
+ std::declval<typename std::iterator_traits<
+ typename Iterable::iterator>::value_type>()))
+ {
+ auto iter = s.begin();
+ auto r = *iter;
+ ++iter;
+ if (iter != s.end())
+ return std::accumulate(iter, s.end(), r, op);
+ else
+ return r;
+ }
+
+ template <class Iterable, class Operator, class T>
+ auto reduce(Operator op, Iterable s, T const &init)
+ -> decltype(std::accumulate(
+ s.begin(), s.end(),
+ static_cast<reduce_helper_t<Iterable, Operator, T>>(init), op))
+ {
+ return std::accumulate(
+ s.begin(), s.end(),
+ static_cast<reduce_helper_t<Iterable, Operator, T>>(init), op);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/reversed.hpp b/contrib/python/pythran/pythran/pythonic/builtins/reversed.hpp
new file mode 100644
index 00000000000..954dd8bb814
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/reversed.hpp
@@ -0,0 +1,60 @@
+#ifndef PYTHONIC_BUILTIN_REVERSED_HPP
+#define PYTHONIC_BUILTIN_REVERSED_HPP
+
+#include "pythonic/include/builtins/reversed.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+ namespace details
+ {
+
+ template <class Iterable>
+ reversed<Iterable>::reversed()
+ {
+ }
+
+ template <class Iterable>
+ reversed<Iterable>::reversed(Iterable const &iterable)
+ : iterable(iterable)
+ {
+ }
+
+ template <class Iterable>
+ typename reversed<Iterable>::iterator reversed<Iterable>::begin()
+ {
+ return iterable.rbegin();
+ }
+
+ template <class Iterable>
+ typename reversed<Iterable>::iterator reversed<Iterable>::end()
+ {
+ return iterable.rend();
+ }
+
+ template <class Iterable>
+ typename reversed<Iterable>::const_iterator
+ reversed<Iterable>::begin() const
+ {
+ return iterable.rbegin();
+ }
+
+ template <class Iterable>
+ typename reversed<Iterable>::const_iterator reversed<Iterable>::end() const
+ {
+ return iterable.rend();
+ }
+ }
+
+ template <class Iterable>
+ details::reversed<Iterable> reversed(Iterable const &iterable)
+ {
+ return {iterable};
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/round.hpp b/contrib/python/pythran/pythran/pythonic/builtins/round.hpp
new file mode 100644
index 00000000000..f9618f77aff
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/round.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_BUILTIN_ROUND_HPP
+#define PYTHONIC_BUILTIN_ROUND_HPP
+
+#include "pythonic/include/builtins/round.hpp"
+
+#include "pythonic/builtins/pow.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ template <class T>
+ double round(T const &v, size_t n)
+ {
+ T p = functor::pow()(10, n);
+ return std::lround(v * p) / p;
+ }
+
+ template <class T>
+ double round(T const &v)
+ {
+ return std::lround(v);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/set.hpp b/contrib/python/pythran/pythran/pythonic/builtins/set.hpp
new file mode 100644
index 00000000000..337f4592e3f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/set.hpp
@@ -0,0 +1,32 @@
+#ifndef PYTHONIC_BUILTIN_SET_HPP
+#define PYTHONIC_BUILTIN_SET_HPP
+
+#include "pythonic/include/builtins/set.hpp"
+
+#include "pythonic/types/set.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace anonymous
+ {
+
+ inline types::empty_set set()
+ {
+ return types::empty_set();
+ }
+
+ template <class Iterable>
+ inline types::set<typename std::iterator_traits<
+ typename std::remove_reference<Iterable>::type::iterator>::value_type>
+ set(Iterable &&t)
+ {
+ return {t.begin(), t.end()};
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/set/add.hpp b/contrib/python/pythran/pythran/pythonic/builtins/set/add.hpp
new file mode 100644
index 00000000000..329536687c3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/set/add.hpp
@@ -0,0 +1,35 @@
+#ifndef PYTHONIC_BUILTIN_SET_ADD_HPP
+#define PYTHONIC_BUILTIN_SET_ADD_HPP
+
+#include "pythonic/include/builtins/set/add.hpp"
+
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/set.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+
+ template <class T, class F>
+ types::none_type add(types::set<T> &s, F const &value)
+ {
+ s.add(value);
+ return builtins::None;
+ }
+
+ template <class T, class F>
+ types::none_type add(types::set<T> &&s, F const &value)
+ {
+ s.add(value);
+ return builtins::None;
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/set/clear.hpp b/contrib/python/pythran/pythran/pythonic/builtins/set/clear.hpp
new file mode 100644
index 00000000000..d855c9c8445
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/set/clear.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_BUILTIN_SET_CLEAR_HPP
+#define PYTHONIC_BUILTIN_SET_CLEAR_HPP
+
+#include "pythonic/include/builtins/set/clear.hpp"
+#include "pythonic/__dispatch__/clear.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/set/copy.hpp b/contrib/python/pythran/pythran/pythonic/builtins/set/copy.hpp
new file mode 100644
index 00000000000..dc309baaa77
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/set/copy.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_BUILTIN_SET_COPY_HPP
+#define PYTHONIC_BUILTIN_SET_COPY_HPP
+
+#include "pythonic/include/builtins/set/copy.hpp"
+#include "pythonic/__dispatch__/copy.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/set/difference.hpp b/contrib/python/pythran/pythran/pythonic/builtins/set/difference.hpp
new file mode 100644
index 00000000000..4edb510b67a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/set/difference.hpp
@@ -0,0 +1,56 @@
+#ifndef PYTHONIC_BUILTIN_SET_DIFFERENCE_HPP
+#define PYTHONIC_BUILTIN_SET_DIFFERENCE_HPP
+
+#include "pythonic/include/builtins/set/difference.hpp"
+
+#include "pythonic/types/set.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+
+ template <typename T, typename... Types>
+ types::set<T> difference(types::set<T> const &set, Types const &...others)
+ {
+ return set.difference(others...);
+ }
+
+ template <typename T, typename... Types>
+ types::set<T> difference(types::set<T> &&set, Types const &...others)
+ {
+ set.difference_update(others...);
+ return set;
+ }
+
+ template <typename... Types>
+ types::empty_set difference(types::empty_set const &set,
+ Types const &...others)
+ {
+ return types::empty_set();
+ }
+
+ template <typename T>
+ types::set<T> difference(types::set<T> const &set)
+ {
+ return set;
+ }
+
+ template <typename T>
+ types::set<T> difference(types::set<T> &&set)
+ {
+ return set;
+ }
+
+ inline types::empty_set difference(types::empty_set const &set)
+ {
+ return types::empty_set();
+ }
+ } // namespace set
+} // namespace builtins
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/set/difference_update.hpp b/contrib/python/pythran/pythran/pythonic/builtins/set/difference_update.hpp
new file mode 100644
index 00000000000..29d18000821
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/set/difference_update.hpp
@@ -0,0 +1,43 @@
+#ifndef PYTHONIC_BUILTIN_SET_DIFFERENCEUPDATE_HPP
+#define PYTHONIC_BUILTIN_SET_DIFFERENCEUPDATE_HPP
+
+#include "pythonic/include/builtins/set/difference_update.hpp"
+
+#include "pythonic/types/set.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+
+ template <typename T, typename... Types>
+ types::none_type difference_update(types::set<T> &set,
+ Types const &... others)
+ {
+ set.difference_update(others...);
+ return {};
+ }
+
+ template <typename T, typename... Types>
+ types::none_type difference_update(types::set<T> &&set,
+ Types const &... others)
+ {
+ // nothing to be done as we work on rvalue
+ return {};
+ }
+
+ template <typename... Types>
+ types::none_type difference_update(types::empty_set const &set,
+ Types const &... others)
+ {
+ // nothing can be removed in set
+ return {};
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/set/discard.hpp b/contrib/python/pythran/pythran/pythonic/builtins/set/discard.hpp
new file mode 100644
index 00000000000..8219da30af6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/set/discard.hpp
@@ -0,0 +1,36 @@
+#ifndef PYTHONIC_BUILTIN_SET_DISCARD_HPP
+#define PYTHONIC_BUILTIN_SET_DISCARD_HPP
+
+#include "pythonic/include/builtins/set/discard.hpp"
+
+#include "pythonic/types/set.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+ template <class T, class U>
+ void discard(types::set<T> &set, U const &elem)
+ {
+ set.discard(elem);
+ }
+
+ template <class T, class U>
+ void discard(types::set<T> &&set, U const &elem)
+ {
+ // nothing to be done for lvalue
+ }
+
+ template <class U>
+ void discard(types::empty_set const &set, U const &elem)
+ {
+ // nothing to remove in an empty_set
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/set/intersection.hpp b/contrib/python/pythran/pythran/pythonic/builtins/set/intersection.hpp
new file mode 100644
index 00000000000..7477fdf0b52
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/set/intersection.hpp
@@ -0,0 +1,39 @@
+#ifndef PYTHONIC_BUILTIN_SET_INTERSECTION_HPP
+#define PYTHONIC_BUILTIN_SET_INTERSECTION_HPP
+
+#include "pythonic/include/builtins/set/intersection.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/set.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+
+ template <typename T, typename... Types>
+ typename __combined<types::set<T>, Types...>::type
+ intersection(types::set<T> const &set, Types const &... others)
+ {
+ return set.intersection(others...);
+ }
+
+ /* No rvalue overload possible because of return type modification.:
+ * >>> a = set([1,2,3])
+ * >>> b = set([1., 2., 3.])
+ * >>> a.intersection(b)
+ * set([1.0, 2.0, 3.0])
+ */
+ template <typename... Types>
+ types::empty_set intersection(types::empty_set const &set,
+ Types const &... others)
+ {
+ return types::empty_set();
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/set/intersection_update.hpp b/contrib/python/pythran/pythran/pythonic/builtins/set/intersection_update.hpp
new file mode 100644
index 00000000000..5bf8b65a814
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/set/intersection_update.hpp
@@ -0,0 +1,44 @@
+#ifndef PYTHONIC_BUILTIN_SET_INTERSECTIONUPDATE_HPP
+#define PYTHONIC_BUILTIN_SET_INTERSECTIONUPDATE_HPP
+
+#include "pythonic/include/builtins/set/intersection_update.hpp"
+
+#include "pythonic/types/set.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+
+ template <typename T, typename... Types>
+ types::none_type intersection_update(types::set<T> &set,
+ Types const &... others)
+ {
+ set.intersection_update(others...);
+ return {};
+ }
+
+ template <typename T, typename... Types>
+ types::none_type intersection_update(types::set<T> &&set,
+ Types const &... others)
+ {
+ // If it is an rvalue, we don't really want to update
+ return {};
+ }
+
+ template <typename... Types>
+ types::none_type intersection_update(types::empty_set &&set,
+ Types const &... others)
+ {
+ // If it is an empty_set, it is ! really updated otherwise we have a
+ // typing issue
+ return {};
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/set/isdisjoint.hpp b/contrib/python/pythran/pythran/pythonic/builtins/set/isdisjoint.hpp
new file mode 100644
index 00000000000..2f5c08794e1
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/set/isdisjoint.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_BUILTIN_SET_ISDISJOINT_HPP
+#define PYTHONIC_BUILTIN_SET_ISDISJOINT_HPP
+
+#include "pythonic/include/builtins/set/isdisjoint.hpp"
+
+#include "pythonic/types/set.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+
+ template <class T, class U>
+ bool isdisjoint(types::set<T> const &calling_set, U const &arg_set)
+ {
+ return calling_set.isdisjoint(arg_set);
+ }
+
+ template <class U>
+ bool isdisjoint(types::empty_set const &calling_set, U const &arg_set)
+ {
+ return true;
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/set/issubset.hpp b/contrib/python/pythran/pythran/pythonic/builtins/set/issubset.hpp
new file mode 100644
index 00000000000..b74680f9187
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/set/issubset.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_BUILTIN_SET_ISSUBSET_HPP
+#define PYTHONIC_BUILTIN_SET_ISSUBSET_HPP
+
+#include "pythonic/include/builtins/set/issubset.hpp"
+
+#include "pythonic/types/set.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+
+ template <class T, class U>
+ bool issubset(types::set<T> const &set, U const &other)
+ {
+ return set.issubset(other);
+ }
+
+ template <class U>
+ bool issubset(types::empty_set const &set, U const &other)
+ {
+ return true;
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/set/issuperset.hpp b/contrib/python/pythran/pythran/pythonic/builtins/set/issuperset.hpp
new file mode 100644
index 00000000000..10da3c1ad3c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/set/issuperset.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_BUILTIN_SET_ISSUPERSET_HPP
+#define PYTHONIC_BUILTIN_SET_ISSUPERSET_HPP
+
+#include "pythonic/include/builtins/set/issuperset.hpp"
+
+#include "pythonic/types/set.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+
+ template <class T, class U>
+ bool issuperset(types::set<T> const &set, U const &other)
+ {
+ return set.issuperset(other);
+ }
+
+ template <class U>
+ bool issuperset(types::empty_set const &set, U const &other)
+ {
+ return false;
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/set/remove.hpp b/contrib/python/pythran/pythran/pythonic/builtins/set/remove.hpp
new file mode 100644
index 00000000000..1035406a697
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/set/remove.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_BUILTIN_SET_REMOVE_HPP
+#define PYTHONIC_BUILTIN_SET_REMOVE_HPP
+
+#include "pythonic/include/builtins/set/remove.hpp"
+#include "pythonic/__dispatch__/remove.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/set/symmetric_difference.hpp b/contrib/python/pythran/pythran/pythonic/builtins/set/symmetric_difference.hpp
new file mode 100644
index 00000000000..b8fd2451936
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/set/symmetric_difference.hpp
@@ -0,0 +1,39 @@
+#ifndef PYTHONIC_BUILTIN_SET_SYMMETRICDIFFERENCE_HPP
+#define PYTHONIC_BUILTIN_SET_SYMMETRICDIFFERENCE_HPP
+
+#include "pythonic/include/builtins/set/symmetric_difference.hpp"
+
+#include "pythonic/types/set.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+
+ template <typename T, typename U>
+ typename __combined<types::set<T>, U>::type
+ symmetric_difference(types::set<T> const &set, U const &other)
+ {
+ return set.symmetric_difference(other);
+ }
+
+ /* No rvalue overload possible because of return type modification.:
+ * >>> a = set([1, 2, 3])
+ * >>> b = set([2., 3., 4.])
+ * >>> a.symmetric_difference(b)
+ * set([1.0, 4.0])
+ */
+ template <typename U>
+ typename __combined<types::empty_set, U>::type
+ symmetric_difference(types::empty_set const &set, U const &other)
+ {
+ return other;
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/set/symmetric_difference_update.hpp b/contrib/python/pythran/pythran/pythonic/builtins/set/symmetric_difference_update.hpp
new file mode 100644
index 00000000000..fcbac1a4290
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/set/symmetric_difference_update.hpp
@@ -0,0 +1,43 @@
+#ifndef PYTHONIC_BUILTIN_SET_SYMMETRICDIFFERENCEUPDATE_HPP
+#define PYTHONIC_BUILTIN_SET_SYMMETRICDIFFERENCEUPDATE_HPP
+
+#include "pythonic/include/builtins/set/symmetric_difference_update.hpp"
+
+#include "pythonic/types/set.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+
+ template <typename T, typename U>
+ types::none_type symmetric_difference_update(types::set<T> &set,
+ U const &other)
+ {
+ set.symmetric_difference_update(other);
+ return {};
+ }
+
+ template <typename T, typename U>
+ types::none_type symmetric_difference_update(types::set<T> &&set,
+ U const &other)
+ {
+ // nothing to be done on rvalue
+ return {};
+ }
+
+ template <typename U>
+ types::none_type symmetric_difference_update(types::empty_set const &set,
+ U const &other)
+ {
+ // nothing otherwise empty_set have ! its correct type.
+ return {};
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/set/union_.hpp b/contrib/python/pythran/pythran/pythonic/builtins/set/union_.hpp
new file mode 100644
index 00000000000..04bcaea0176
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/set/union_.hpp
@@ -0,0 +1,50 @@
+#ifndef PYTHONIC_BUILTIN_SET_UNION_HPP
+#define PYTHONIC_BUILTIN_SET_UNION_HPP
+
+#include "pythonic/include/builtins/set/union_.hpp"
+
+#include "pythonic/types/set.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+
+ template <typename T, typename... Types>
+ typename __combined<types::set<T>, Types...>::type
+ union_(types::set<T> const &set, Types const &...others)
+ {
+ return set.union_(others...);
+ }
+
+ template <typename... Types>
+ typename __combined<types::empty_set, Types...>::type
+ union_(types::empty_set const &init, Types const &...others)
+ {
+ return union_(others...);
+ }
+
+ template <typename T>
+ types::set<T> union_(types::set<T> const &set)
+ {
+ return set;
+ }
+
+ template <typename T>
+ typename __combined<types::empty_set, T>::type union_(T const &set)
+ {
+ return {set};
+ }
+
+ inline types::empty_set union_(types::empty_set const &init)
+ {
+ return types::empty_set();
+ }
+ } // namespace set
+} // namespace builtins
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/set/update.hpp b/contrib/python/pythran/pythran/pythonic/builtins/set/update.hpp
new file mode 100644
index 00000000000..673a6e192b1
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/set/update.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_SET_UPDATE_HPP
+#define PYTHONIC_SET_UPDATE_HPP
+
+#include "pythonic/include/builtins/set/update.hpp"
+#include "pythonic/__dispatch__/update.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/slice.hpp b/contrib/python/pythran/pythran/pythonic/builtins/slice.hpp
new file mode 100644
index 00000000000..3a96dc79212
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/slice.hpp
@@ -0,0 +1,32 @@
+#ifndef PYTHONIC_BUILTIN_SLICE_HPP
+#define PYTHONIC_BUILTIN_SLICE_HPP
+
+#include "pythonic/include/builtins/slice.hpp"
+#include "pythonic/types/slice.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace anonymous
+ {
+ inline types::cstride_slice<1> slice(types::none<long> stop)
+ {
+ return {types::none<long>(), stop};
+ }
+ inline types::cstride_slice<1> slice(types::none<long> start,
+ types::none<long> stop)
+ {
+ return {start, stop};
+ }
+ inline types::slice slice(types::none<long> start, types::none<long> stop,
+ types::none<long> step)
+ {
+ return {start, stop, step};
+ }
+ } // namespace anonymous
+} // namespace builtins
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/sorted.hpp b/contrib/python/pythran/pythran/pythonic/builtins/sorted.hpp
new file mode 100644
index 00000000000..8e247435a0e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/sorted.hpp
@@ -0,0 +1,70 @@
+#ifndef PYTHONIC_BUILTIN_SORTED_HPP
+#define PYTHONIC_BUILTIN_SORTED_HPP
+
+#include "pythonic/include/builtins/sorted.hpp"
+
+#include "pythonic/types/list.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/pdqsort.hpp"
+
+#include <algorithm>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ template <class Iterable>
+ types::list<typename std::remove_cv<typename std::iterator_traits<
+ typename std::decay<Iterable>::type::iterator>::value_type>::type>
+ sorted(Iterable &&seq)
+ {
+ types::list<typename std::remove_cv<typename std::iterator_traits<
+ typename std::decay<Iterable>::type::iterator>::value_type>::type>
+ out(seq.begin(), seq.end());
+ pdqsort(out.begin(), out.end());
+ return out;
+ }
+
+ template <class Iterable, class Key>
+ types::list<typename std::remove_cv<typename std::iterator_traits<
+ typename std::decay<Iterable>::type::iterator>::value_type>::type>
+ sorted(Iterable &&seq, Key const &key, bool reverse)
+ {
+ using value_type = typename std::remove_cv<typename std::iterator_traits<
+ typename std::decay<Iterable>::type::iterator>::value_type>::type;
+ types::list<value_type> out(seq.begin(), seq.end());
+ if (reverse)
+ pdqsort(out.begin(), out.end(),
+ [&key](value_type const &self, value_type const &other) {
+ return key(self) > key(other);
+ });
+ else
+ pdqsort(out.begin(), out.end(),
+ [&key](value_type const &self, value_type const &other) {
+ return key(self) < key(other);
+ });
+ return out;
+ }
+
+ template <class Iterable>
+ types::list<typename std::remove_cv<typename std::iterator_traits<
+ typename std::decay<Iterable>::type::iterator>::value_type>::type>
+ sorted(Iterable &&seq, types::none_type const &key, bool reverse)
+ {
+ using value_type = typename std::remove_cv<typename std::iterator_traits<
+ typename std::decay<Iterable>::type::iterator>::value_type>::type;
+ types::list<value_type> out(seq.begin(), seq.end());
+ if (reverse)
+ pdqsort(out.begin(), out.end(),
+ [](value_type const &self, value_type const &other) {
+ return self > other;
+ });
+ else
+ pdqsort(out.begin(), out.end());
+ return out;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/str/__mod__.hpp b/contrib/python/pythran/pythran/pythonic/builtins/str/__mod__.hpp
new file mode 100644
index 00000000000..812f1abf23a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/str/__mod__.hpp
@@ -0,0 +1,58 @@
+#ifndef PYTHONIC_BUILTIN_STR_MOD_HPP
+#define PYTHONIC_BUILTIN_STR_MOD_HPP
+
+#include "pythonic/builtins/str/__mod__.hpp"
+
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <boost/format.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ namespace details
+ {
+ template <class Tuple>
+ void fmt(boost::format &f, Tuple const &a, utils::int_<1>)
+ {
+ f % std::get<std::tuple_size<Tuple>::value - 1>(a);
+ }
+ template <class Tuple, size_t I>
+ void fmt(boost::format &f, Tuple const &a, utils::int_<I>)
+ {
+ fmt(f % std::get<std::tuple_size<Tuple>::value - I>(a), a,
+ utils::int_<I - 1>());
+ }
+ }
+
+ template <class T>
+ types::str __mod__(types::str const &s, T const &arg)
+ {
+ const boost::format fmter(s.chars());
+ return (boost::format(fmter) % arg).str();
+ }
+
+ template <class... Ts>
+ types::str __mod__(types::str const &s, std::tuple<Ts...> const &args)
+ {
+ boost::format fmter(s.chars());
+ details::fmt(fmter, args, utils::int_<sizeof...(Ts)>());
+ return fmter.str();
+ }
+ template <size_t N, class T>
+ types::str __mod__(types::str const &s, types::array<T, N> const &args)
+ {
+ boost::format fmter(s.chars());
+ details::fmt(fmter, args, utils::int_<N>());
+ return fmter.str();
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/str/capitalize.hpp b/contrib/python/pythran/pythran/pythonic/builtins/str/capitalize.hpp
new file mode 100644
index 00000000000..5102d46dbc0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/str/capitalize.hpp
@@ -0,0 +1,32 @@
+#ifndef PYTHONIC_BUILTIN_STR_CAPITALIZE_HPP
+#define PYTHONIC_BUILTIN_STR_CAPITALIZE_HPP
+
+#include "pythonic/include/builtins/str/capitalize.hpp"
+
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ types::str capitalize(types::str const &s)
+ {
+ if (s.empty())
+ return s;
+ else {
+ types::str copy = s;
+ copy.chars()[0] = ::toupper(s.chars()[0]);
+ std::transform(s.chars().begin() + 1, s.chars().end(),
+ copy.chars().begin() + 1, ::tolower);
+ return copy;
+ }
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/str/count.hpp b/contrib/python/pythran/pythran/pythonic/builtins/str/count.hpp
new file mode 100644
index 00000000000..2a9f6b5ec38
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/str/count.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_BUILTIN_STR_COUNT_HPP
+#define PYTHONIC_BUILTIN_STR_COUNT_HPP
+
+#include "pythonic/include/builtins/str/count.hpp"
+#include "pythonic/__dispatch__/count.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/str/endswith.hpp b/contrib/python/pythran/pythran/pythonic/builtins/str/endswith.hpp
new file mode 100644
index 00000000000..b8df066ce69
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/str/endswith.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_BUILTIN_STR_ENDSWITH_HPP
+#define PYTHONIC_BUILTIN_STR_ENDSWITH_HPP
+
+#include "pythonic/include/builtins/str/endswith.hpp"
+
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ bool endswith(types::str const &s, types::str const &suffix, long start,
+ long end)
+ {
+ if (end == -1)
+ end = s.size();
+ long rstart = end - suffix.size();
+ return rstart >= start && s.compare(rstart, suffix.size(), suffix) == 0;
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/str/find.hpp b/contrib/python/pythran/pythran/pythonic/builtins/str/find.hpp
new file mode 100644
index 00000000000..20454838f6e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/str/find.hpp
@@ -0,0 +1,38 @@
+#ifndef PYTHONIC_BUILTIN_STR_FIND_HPP
+#define PYTHONIC_BUILTIN_STR_FIND_HPP
+
+#include "pythonic/include/builtins/str/find.hpp"
+
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ inline long find(types::str const &s, types::str const &value, long start,
+ long end)
+ {
+ if (end < 0)
+ end += s.size();
+ long a = s.find(value, start);
+ return (a > end) ? -1 : a;
+ }
+
+ inline long find(types::str const &s, types::str const &value, long start)
+ {
+ return find(s, value, start, s.size());
+ }
+
+ inline long find(types::str const &s, types::str const &value)
+ {
+ return find(s, value, 0, s.size());
+ }
+ } // namespace str
+} // namespace builtins
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/str/isalpha.hpp b/contrib/python/pythran/pythran/pythonic/builtins/str/isalpha.hpp
new file mode 100644
index 00000000000..e7d9beaa704
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/str/isalpha.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_BUILTIN_STR_ISALPHA_HPP
+#define PYTHONIC_BUILTIN_STR_ISALPHA_HPP
+
+#include "pythonic/include/builtins/str/isalpha.hpp"
+
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ bool isalpha(types::str const &s)
+ {
+ return !s.empty() && std::all_of(s.chars().begin(), s.chars().end(),
+ (int (*)(int))std::isalpha);
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/str/isdigit.hpp b/contrib/python/pythran/pythran/pythonic/builtins/str/isdigit.hpp
new file mode 100644
index 00000000000..58da6227c4d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/str/isdigit.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_BUILTIN_STR_ISDIGIT_HPP
+#define PYTHONIC_BUILTIN_STR_ISDIGIT_HPP
+
+#include "pythonic/include/builtins/str/isdigit.hpp"
+
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <cctype>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ bool isdigit(types::str const &s)
+ {
+ return !s.empty() && std::all_of(s.chars().begin(), s.chars().end(),
+ (int (*)(int))std::isdigit);
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/str/join.hpp b/contrib/python/pythran/pythran/pythonic/builtins/str/join.hpp
new file mode 100644
index 00000000000..af966c789b0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/str/join.hpp
@@ -0,0 +1,118 @@
+#ifndef PYTHONIC_BUILTIN_STR_JOIN_HPP
+#define PYTHONIC_BUILTIN_STR_JOIN_HPP
+
+#include "pythonic/include/builtins/str/join.hpp"
+
+#include "pythonic/builtins/len.hpp"
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ template <class S>
+ types::str join(S const &s, types::str const &iterable)
+ {
+ long ssize = std::distance(std::begin(s), std::end(s)) -
+ (std::is_same<S, types::str>::value ? 0 : 1);
+ /* first iterate over iterable to gather sizes */
+ size_t n = ssize * (iterable.size() - 1) + iterable.size();
+
+ std::string out(n, 0);
+
+ auto iter = iterable.chars().begin();
+ auto oter = out.begin();
+ if (iter != iterable.chars().end()) {
+ *oter++ = *iter++;
+ if (ssize)
+ for (; iter != iterable.chars().end(); ++iter) {
+ for (auto &&v : s)
+ *oter++ = v.chars()[0];
+ *oter++ = *iter;
+ }
+ else
+ std::copy(iter, iterable.chars().end(), oter);
+ }
+ return {std::move(out)};
+ }
+
+ template <class S, class Iterable>
+ typename std::enable_if<
+ !std::is_same<typename std::remove_cv<
+ typename std::remove_reference<Iterable>::type>::type,
+ types::str>::value &&
+ std::is_same<
+ typename std::iterator_traits<typename std::remove_reference<
+ Iterable>::type::iterator>::iterator_category,
+ std::random_access_iterator_tag>::value,
+ types::str>::type
+ join(S const &s, Iterable &&iterable)
+ {
+ long ssize = builtins::functor::len{}(s);
+
+ /* first iterate over iterable to gather sizes */
+ long iterable_size = std::distance(iterable.begin(), iterable.end());
+ if (iterable_size == 0)
+ return "";
+ size_t n = ssize * (iterable_size - 1);
+ for (auto const &iter : iterable)
+ n += builtins::len(iter);
+
+ std::string out(n, 0);
+
+ auto iter = iterable.begin();
+ auto oter = out.begin();
+ if (iter != iterable.end()) {
+ auto tmp = *iter;
+ auto const &stmp = tmp.chars();
+ oter = std::copy(stmp.begin(), stmp.end(), oter);
+ ++iter;
+ if (ssize)
+ for (; iter != iterable.end(); ++iter) {
+ auto chars = s.chars();
+ oter =
+ std::copy(std::begin(chars), std::begin(chars) + ssize, oter);
+ auto tmp = *iter;
+ auto const &stmp = tmp.chars();
+ oter = std::copy(stmp.begin(), stmp.end(), oter);
+ }
+ else
+ for (; iter != iterable.end(); ++iter) {
+ auto tmp = (*iter);
+ auto const &stmp = tmp.chars();
+ oter = std::copy(stmp.begin(), stmp.end(), oter);
+ }
+ }
+ return {std::move(out)};
+ }
+
+ template <class S, class Iterable>
+ typename std::enable_if<
+ !std::is_same<
+ typename std::iterator_traits<typename std::remove_reference<
+ Iterable>::type::iterator>::iterator_category,
+ std::random_access_iterator_tag>::value,
+ types::str>::type
+ join(S const &s, Iterable &&iterable)
+ {
+ types::str out;
+ auto iter = iterable.begin();
+ if (iter != iterable.end()) {
+ out += *iter;
+ ++iter;
+ for (; iter != iterable.end(); ++iter) {
+ out += s;
+ out += *iter;
+ }
+ }
+ return out;
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/str/lower.hpp b/contrib/python/pythran/pythran/pythonic/builtins/str/lower.hpp
new file mode 100644
index 00000000000..6d2bcd6cb9c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/str/lower.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_BUILTIN_STR_LOWER_HPP
+#define PYTHONIC_BUILTIN_STR_LOWER_HPP
+
+#include "pythonic/include/builtins/str/lower.hpp"
+
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ types::str lower(types::str const &s)
+ {
+ types::str copy = s;
+ std::transform(s.chars().begin(), s.chars().end(), copy.chars().begin(),
+ ::tolower);
+ return copy;
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/str/lstrip.hpp b/contrib/python/pythran/pythran/pythonic/builtins/str/lstrip.hpp
new file mode 100644
index 00000000000..d3a031bfede
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/str/lstrip.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_BUILTIN_STR_LSTRIP_HPP
+#define PYTHONIC_BUILTIN_STR_LSTRIP_HPP
+
+#include "pythonic/include/builtins/str/lstrip.hpp"
+
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ types::str lstrip(types::str const &self, types::str const &to_del)
+ {
+ auto chars = self.chars();
+ auto stop = self.find_first_not_of(to_del);
+ if (stop < 0)
+ return {};
+ else
+ return {chars.begin() + stop, chars.end()};
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/str/replace.hpp b/contrib/python/pythran/pythran/pythonic/builtins/str/replace.hpp
new file mode 100644
index 00000000000..7bd78647497
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/str/replace.hpp
@@ -0,0 +1,53 @@
+#ifndef PYTHONIC_BUILTIN_STR_REPLACE_HPP
+#define PYTHONIC_BUILTIN_STR_REPLACE_HPP
+
+#include "pythonic/include/builtins/str/replace.hpp"
+
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/allocate.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ types::str replace(types::str const &self, types::str const &old_pattern,
+ types::str const &new_pattern, long count)
+ {
+ char const *needle = old_pattern.c_str();
+ char const *new_needle = new_pattern.c_str();
+ char const *new_needle_end = new_needle + new_pattern.size();
+ char const *haystack = self.c_str();
+
+ char const *haystack_next = strstr(haystack, needle);
+ if (!count || !haystack_next) {
+ return {haystack};
+ } else {
+ size_t n =
+ 1 + std::max(self.size(), self.size() * (1 + new_pattern.size()) /
+ (1 + old_pattern.size()));
+
+ char *buffer = utils::allocate<char>(n);
+ char *iter = buffer;
+ do {
+ iter = std::copy(haystack, haystack_next, iter);
+ iter = std::copy(new_needle, new_needle_end, iter);
+ --count;
+ haystack = haystack_next + old_pattern.size();
+ assert(size_t(iter - buffer) < n);
+ } while (count && (haystack_next = strstr(haystack, needle)));
+
+ iter = std::copy(haystack, self.c_str() + self.size(), iter);
+ types::str replaced(buffer, iter - buffer);
+ utils::deallocate(buffer);
+ return replaced;
+ }
+ }
+ } // namespace str
+} // namespace builtins
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/str/rstrip.hpp b/contrib/python/pythran/pythran/pythonic/builtins/str/rstrip.hpp
new file mode 100644
index 00000000000..a1536478bd1
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/str/rstrip.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_BUILTIN_STR_RSTRIP_HPP
+#define PYTHONIC_BUILTIN_STR_RSTRIP_HPP
+
+#include "pythonic/include/builtins/str/rstrip.hpp"
+
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ types::str rstrip(types::str const &self, types::str const &to_del)
+ {
+ auto chars = self.chars();
+ auto stop = self.find_last_not_of(to_del);
+ if (stop < 0)
+ return {};
+ return {chars.begin(), chars.begin() + stop + 1};
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/str/split.hpp b/contrib/python/pythran/pythran/pythonic/builtins/str/split.hpp
new file mode 100644
index 00000000000..c7a20ee8b3a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/str/split.hpp
@@ -0,0 +1,72 @@
+#ifndef PYTHONIC_BUILTIN_STR_SPLIT_HPP
+#define PYTHONIC_BUILTIN_STR_SPLIT_HPP
+
+#include "pythonic/include/builtins/str/split.hpp"
+
+#include "pythonic/builtins/str/strip.hpp"
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/list.hpp"
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ inline types::list<types::str> split(types::str const &in,
+ types::str const &sep, long maxsplit)
+ {
+ types::str s = strip(in);
+ types::list<types::str> res(0);
+ if (s.empty())
+ return res;
+
+ size_t current = 0;
+ size_t next = 0;
+ long numsplit = 0;
+ while (next != types::str::npos &&
+ (numsplit++ < maxsplit || maxsplit == -1)) {
+ next = s.find_first_of(sep, current);
+ res.push_back(s.substr(current, next - current));
+ current = next + 1;
+ }
+ if (next != types::str::npos) {
+ current = next + 1;
+ res.push_back(s.substr(current, s.size() - current));
+ }
+ return res;
+ }
+
+ inline types::list<types::str>
+ split(types::str const &in, types::none_type const &, long maxsplit)
+ {
+ types::str s = strip(in);
+ types::list<types::str> res(0);
+ if (s.empty())
+ return res;
+
+ size_t current = 0;
+ size_t next = 0;
+ long numsplit = 0;
+ while (next != types::str::npos &&
+ (numsplit++ < maxsplit || maxsplit == -1)) {
+ next = s.find_first_of(" \n\r\t", current);
+ // from the pydoc, we skip any blank list
+ size_t end = s.find_first_not_of(" \n\r\t", next);
+ res.push_back(s.substr(current, next - current));
+ current = end;
+ }
+ if (next != types::str::npos) {
+ current = next + 1;
+ res.push_back(s.substr(current, s.size() - current));
+ }
+ return res;
+ }
+ } // namespace str
+} // namespace builtins
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/str/startswith.hpp b/contrib/python/pythran/pythran/pythonic/builtins/str/startswith.hpp
new file mode 100644
index 00000000000..1d297f4c87e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/str/startswith.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_BUILTIN_STR_STARTSWITH_HPP
+#define PYTHONIC_BUILTIN_STR_STARTSWITH_HPP
+
+#include "pythonic/include/builtins/str/startswith.hpp"
+
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ bool startswith(types::str const &s, types::str const &prefix, long start,
+ long end)
+ {
+ if (end < 0)
+ end = s.size();
+ return (end - start) >= prefix.size() &&
+ s.compare(start, prefix.size(), prefix) == 0;
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/str/strip.hpp b/contrib/python/pythran/pythran/pythonic/builtins/str/strip.hpp
new file mode 100644
index 00000000000..c580a63a8a3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/str/strip.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_BUILTIN_STR_STRIP_HPP
+#define PYTHONIC_BUILTIN_STR_STRIP_HPP
+
+#include "pythonic/include/builtins/str/strip.hpp"
+
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+ types::str strip(types::str const &self, types::str const &to_del)
+ {
+ if (!self)
+ return self;
+ auto first = self.find_first_not_of(to_del);
+ if (first == -1)
+ return types::str();
+ else
+ return types::str(self.chars().begin() + first,
+ self.chars().begin() + self.find_last_not_of(to_del) +
+ 1);
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/str/upper.hpp b/contrib/python/pythran/pythran/pythonic/builtins/str/upper.hpp
new file mode 100644
index 00000000000..1f8d38a8840
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/str/upper.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_BUILTIN_STR_UPPER_HPP
+#define PYTHONIC_BUILTIN_STR_UPPER_HPP
+
+#include "pythonic/include/builtins/str/upper.hpp"
+
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ types::str upper(types::str const &s)
+ {
+ types::str copy = s;
+ std::transform(s.chars().begin(), s.chars().end(), copy.chars().begin(),
+ ::toupper);
+ return copy;
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/sum.hpp b/contrib/python/pythran/pythran/pythonic/builtins/sum.hpp
new file mode 100644
index 00000000000..5c35f1c4a66
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/sum.hpp
@@ -0,0 +1,49 @@
+#ifndef PYTHONIC_BUILTIN_SUM_HPP
+#define PYTHONIC_BUILTIN_SUM_HPP
+
+#include "pythonic/include/builtins/sum.hpp"
+
+#include "pythonic/types/assignable.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/int_.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace details
+ {
+ template <class Tuple, size_t N>
+ auto tuple_sum<Tuple, N>::operator()(Tuple const &t)
+ -> decltype(std::get<N>(t) + tuple_sum<Tuple, N - 1>()(t))
+ {
+ return std::get<N>(t) + tuple_sum<Tuple, N - 1>()(t);
+ }
+
+ template <class Tuple>
+ auto tuple_sum<Tuple, 0>::operator()(Tuple const &t)
+ -> decltype(std::get<0>(t))
+ {
+ return std::get<0>(t);
+ }
+ }
+
+ template <class Iterable, class T>
+ auto sum(Iterable s, T start) -> decltype(std::accumulate(
+ s.begin(), s.end(),
+ static_cast<typename assignable<decltype(start + *s.begin())>::type>(
+ start)))
+ {
+ return std::accumulate(
+ s.begin(), s.end(),
+ static_cast<typename assignable<decltype(start + *s.begin())>::type>(
+ start));
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/type.hpp b/contrib/python/pythran/pythran/pythonic/builtins/type.hpp
new file mode 100644
index 00000000000..55b530a80b2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/type.hpp
@@ -0,0 +1,148 @@
+#ifndef PYTHONIC_BUILTIN_TYPE_HPP
+#define PYTHONIC_BUILTIN_TYPE_HPP
+
+#include "pythonic/include/builtins/type.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+#include "pythonic/builtins/bool_.hpp"
+#include "pythonic/builtins/int_.hpp"
+#include "pythonic/builtins/float_.hpp"
+#include "pythonic/builtins/complex.hpp"
+#include "pythonic/builtins/set.hpp"
+#include "pythonic/builtins/str.hpp"
+#include "pythonic/builtins/list.hpp"
+#include "pythonic/builtins/dict.hpp"
+#include "pythonic/builtins/tuple.hpp"
+#include "pythonic/numpy/array.hpp"
+#include "pythonic/numpy/byte.hpp"
+#include "pythonic/numpy/ubyte.hpp"
+#include "pythonic/numpy/short_.hpp"
+#include "pythonic/numpy/ushort.hpp"
+#include "pythonic/numpy/intc.hpp"
+#include "pythonic/numpy/uintc.hpp"
+#include "pythonic/numpy/int_.hpp"
+#include "pythonic/numpy/uint.hpp"
+#include "pythonic/numpy/longlong.hpp"
+#include "pythonic/numpy/ulonglong.hpp"
+#include "pythonic/numpy/float32.hpp"
+#include "pythonic/numpy/float128.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+ template <>
+ struct type_functor<bool> {
+ using type = functor::bool_;
+ };
+ template <>
+ struct type_functor<double> {
+ using type = functor::float_;
+ };
+ template <>
+ struct type_functor<types::str> {
+ using type = functor::str;
+ };
+ template <class T>
+ struct type_functor<std::complex<T>> {
+ using type = functor::complex;
+ };
+ template <>
+ struct type_functor<types::empty_set> {
+ using type = functor::set;
+ };
+ template <class T>
+ struct type_functor<types::set<T>> {
+ using type = functor::set;
+ };
+ template <>
+ struct type_functor<types::empty_list> {
+ using type = functor::list;
+ };
+ template <class T>
+ struct type_functor<types::list<T>> {
+ using type = functor::list;
+ };
+ template <class T, size_t N>
+ struct type_functor<types::static_list<T, N>> {
+ using type = functor::list;
+ };
+ template <>
+ struct type_functor<types::empty_dict> {
+ using type = functor::dict;
+ };
+ template <class K, class V>
+ struct type_functor<types::dict<K, V>> {
+ using type = functor::dict;
+ };
+ template <class... Tys>
+ struct type_functor<std::tuple<Tys...>> {
+ using type = functor::tuple;
+ };
+ template <class T, size_t N>
+ struct type_functor<types::array<T, N>> {
+ using type = functor::tuple;
+ };
+ template <class T, class pS>
+ struct type_functor<types::ndarray<T, pS>> {
+ using type = numpy::functor::array;
+ };
+ template <>
+ struct type_functor<signed char> {
+ using type = numpy::functor::byte;
+ };
+ template <>
+ struct type_functor<unsigned char> {
+ using type = numpy::functor::ubyte;
+ };
+ template <>
+ struct type_functor<short> {
+ using type = numpy::functor::short_;
+ };
+ template <>
+ struct type_functor<unsigned short> {
+ using type = numpy::functor::ushort;
+ };
+ template <>
+ struct type_functor<int> {
+ using type = numpy::functor::intc;
+ };
+ template <>
+ struct type_functor<unsigned int> {
+ using type = numpy::functor::uintc;
+ };
+ template <>
+ struct type_functor<long> {
+ using type = numpy::functor::int_;
+ };
+ template <>
+ struct type_functor<unsigned long> {
+ using type = numpy::functor::uint;
+ };
+ template <>
+ struct type_functor<long long> {
+ using type = numpy::functor::longlong;
+ };
+ template <>
+ struct type_functor<unsigned long long> {
+ using type = numpy::functor::ulonglong;
+ };
+ template <>
+ struct type_functor<float> {
+ using type = numpy::functor::float32;
+ };
+ template <>
+ struct type_functor<long double> {
+ using type = numpy::functor::float128;
+ };
+
+ template <class T>
+ typename type_functor<T>::type type(T const &)
+ {
+ return {};
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/xrange.hpp b/contrib/python/pythran/pythran/pythonic/builtins/xrange.hpp
new file mode 100644
index 00000000000..2436fa470c0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/xrange.hpp
@@ -0,0 +1,108 @@
+#ifndef PYTHONIC_BUILTIN_XRANGE_HPP
+#define PYTHONIC_BUILTIN_XRANGE_HPP
+
+#include "pythonic/include/builtins/xrange.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+#include <iterator>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace
+ {
+
+ long _init_last(long _begin, long _end, long _step)
+ {
+ if (_step > 0)
+ return _begin +
+ std::max(0L, _step * ((_end - _begin + _step - 1) / _step));
+ else
+ return _begin +
+ std::min(0L, _step * ((_end - _begin + _step + 1) / _step));
+ }
+ }
+
+ xrange_iterator::xrange_iterator(long v, long s) : value_(v), step_(s)
+ {
+ }
+
+ long xrange_iterator::operator*() const
+ {
+ return value_;
+ }
+
+ xrange_iterator &xrange_iterator::operator++()
+ {
+ value_ += step_;
+ return *this;
+ }
+
+ xrange_iterator xrange_iterator::operator++(int)
+ {
+ xrange_iterator self(*this);
+ value_ += step_;
+ return self;
+ }
+
+ xrange_iterator &xrange_iterator::operator+=(long n)
+ {
+ value_ += step_ * n;
+ return *this;
+ }
+
+ bool xrange_iterator::operator!=(xrange_iterator const &other) const
+ {
+ return value_ != other.value_;
+ }
+
+ bool xrange_iterator::operator==(xrange_iterator const &other) const
+ {
+ return value_ == other.value_;
+ }
+
+ bool xrange_iterator::operator<(xrange_iterator const &other) const
+ {
+ return step_ * value_ < step_ * other.value_;
+ }
+
+ long xrange_iterator::operator-(xrange_iterator const &other) const
+ {
+ return (value_ - other.value_) / step_;
+ }
+
+ xrange::xrange(long b, long e, long s)
+ : begin_(b), end_(_init_last(b, e, s)), step_(s)
+ {
+ }
+
+ xrange::xrange(long e) : begin_(0), end_(e), step_(1)
+ {
+ }
+
+ xrange_iterator xrange::begin() const
+ {
+ return xrange_iterator(begin_, step_);
+ }
+
+ xrange_iterator xrange::end() const
+ {
+ return xrange_iterator(end_, step_);
+ }
+
+ typename xrange::reverse_iterator xrange::rbegin() const
+ {
+ return {end_ - step_, -step_};
+ }
+
+ typename xrange::reverse_iterator xrange::rend() const
+ {
+ return {begin_ - step_, -step_};
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/builtins/zip.hpp b/contrib/python/pythran/pythran/pythonic/builtins/zip.hpp
new file mode 100644
index 00000000000..84f7bf8e558
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/builtins/zip.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_BUILTIN_ZIP_HPP
+#define PYTHONIC_BUILTIN_ZIP_HPP
+
+#include "pythonic/include/builtins/zip.hpp"
+
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/builtins/map.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ template <typename... Iter>
+ auto zip(Iter &&... iters)
+ -> decltype(map(builtins::None, std::forward<Iter>(iters)...))
+ {
+ return map(builtins::None, std::forward<Iter>(iters)...);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/cmath/acos.hpp b/contrib/python/pythran/pythran/pythonic/cmath/acos.hpp
new file mode 100644
index 00000000000..d35580c144e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/cmath/acos.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_CMATH_ACOS_HPP
+#define PYTHONIC_CMATH_ACOS_HPP
+
+#include "pythonic/include/cmath/acos.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/cmath/acosh.hpp b/contrib/python/pythran/pythran/pythonic/cmath/acosh.hpp
new file mode 100644
index 00000000000..09193d0d3a2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/cmath/acosh.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_CMATH_ACOSH_HPP
+#define PYTHONIC_CMATH_ACOSH_HPP
+
+#include "pythonic/include/cmath/acosh.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/cmath/asin.hpp b/contrib/python/pythran/pythran/pythonic/cmath/asin.hpp
new file mode 100644
index 00000000000..a18a35b291f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/cmath/asin.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_CMATH_ASIN_HPP
+#define PYTHONIC_CMATH_ASIN_HPP
+
+#include "pythonic/include/cmath/asin.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/cmath/asinh.hpp b/contrib/python/pythran/pythran/pythonic/cmath/asinh.hpp
new file mode 100644
index 00000000000..d460ba71faf
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/cmath/asinh.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_CMATH_ASINH_HPP
+#define PYTHONIC_CMATH_ASINH_HPP
+
+#include "pythonic/include/cmath/asinh.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/cmath/atan.hpp b/contrib/python/pythran/pythran/pythonic/cmath/atan.hpp
new file mode 100644
index 00000000000..ecc5020e8db
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/cmath/atan.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_CMATH_ATAN_HPP
+#define PYTHONIC_CMATH_ATAN_HPP
+
+#include "pythonic/include/cmath/atan.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/cmath/atanh.hpp b/contrib/python/pythran/pythran/pythonic/cmath/atanh.hpp
new file mode 100644
index 00000000000..997c74310f2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/cmath/atanh.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_CMATH_ATANH_HPP
+#define PYTHONIC_CMATH_ATANH_HPP
+
+#include "pythonic/include/cmath/atanh.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/cmath/cos.hpp b/contrib/python/pythran/pythran/pythonic/cmath/cos.hpp
new file mode 100644
index 00000000000..fe4965949fb
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/cmath/cos.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_CMATH_COS_HPP
+#define PYTHONIC_CMATH_COS_HPP
+
+#include "pythonic/include/cmath/cos.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+ template <class T>
+ std::complex<T> cos(std::complex<T> const &v)
+ {
+ return std::cos(v);
+ }
+
+ template <class T>
+ std::complex<T> cos(T const &v)
+ {
+ return std::cos(v);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/cmath/cosh.hpp b/contrib/python/pythran/pythran/pythonic/cmath/cosh.hpp
new file mode 100644
index 00000000000..671143a91bd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/cmath/cosh.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_CMATH_COSH_HPP
+#define PYTHONIC_CMATH_COSH_HPP
+
+#include "pythonic/include/cmath/cosh.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/cmath/e.hpp b/contrib/python/pythran/pythran/pythonic/cmath/e.hpp
new file mode 100644
index 00000000000..bd8235ff43f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/cmath/e.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_CMATH_E_HPP
+#define PYTHONIC_CMATH_E_HPP
+
+#include "pythonic/include/cmath/e.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/cmath/exp.hpp b/contrib/python/pythran/pythran/pythonic/cmath/exp.hpp
new file mode 100644
index 00000000000..aa06a419b31
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/cmath/exp.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_CMATH_EXP_HPP
+#define PYTHONIC_CMATH_EXP_HPP
+
+#include "pythonic/include/cmath/exp.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/cmath/isinf.hpp b/contrib/python/pythran/pythran/pythonic/cmath/isinf.hpp
new file mode 100644
index 00000000000..c2f012b8e31
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/cmath/isinf.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_CMATH_ISINF_HPP
+#define PYTHONIC_CMATH_ISINF_HPP
+
+#include "pythonic/include/cmath/isinf.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/cmath/isnan.hpp b/contrib/python/pythran/pythran/pythonic/cmath/isnan.hpp
new file mode 100644
index 00000000000..969dc7461ae
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/cmath/isnan.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_CMATH_ISNAN_HPP
+#define PYTHONIC_CMATH_ISNAN_HPP
+
+#include "pythonic/include/cmath/isnan.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/cmath/log.hpp b/contrib/python/pythran/pythran/pythonic/cmath/log.hpp
new file mode 100644
index 00000000000..8c8fe36930b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/cmath/log.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_CMATH_LOG_HPP
+#define PYTHONIC_CMATH_LOG_HPP
+
+#include "pythonic/include/cmath/log.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+ using std::log;
+ double log(double x, double base)
+ {
+ return log(x) / log(base);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/cmath/log10.hpp b/contrib/python/pythran/pythran/pythonic/cmath/log10.hpp
new file mode 100644
index 00000000000..86c3c793916
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/cmath/log10.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_CMATH_LOG10_HPP
+#define PYTHONIC_CMATH_LOG10_HPP
+
+#include "pythonic/include/cmath/log10.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/cmath/pi.hpp b/contrib/python/pythran/pythran/pythonic/cmath/pi.hpp
new file mode 100644
index 00000000000..cfa87d79e35
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/cmath/pi.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_CMATH_PI_HPP
+#define PYTHONIC_CMATH_PI_HPP
+
+#include "pythonic/include/cmath/pi.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/cmath/sin.hpp b/contrib/python/pythran/pythran/pythonic/cmath/sin.hpp
new file mode 100644
index 00000000000..5dcec69e746
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/cmath/sin.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_CMATH_SIN_HPP
+#define PYTHONIC_CMATH_SIN_HPP
+
+#include "pythonic/include/cmath/sin.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/cmath/sinh.hpp b/contrib/python/pythran/pythran/pythonic/cmath/sinh.hpp
new file mode 100644
index 00000000000..891d543f066
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/cmath/sinh.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_CMATH_SINH_HPP
+#define PYTHONIC_CMATH_SINH_HPP
+
+#include "pythonic/include/cmath/sinh.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/cmath/sqrt.hpp b/contrib/python/pythran/pythran/pythonic/cmath/sqrt.hpp
new file mode 100644
index 00000000000..f84a6293ed3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/cmath/sqrt.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_CMATH_SQRT_HPP
+#define PYTHONIC_CMATH_SQRT_HPP
+
+#include "pythonic/include/cmath/sqrt.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/cmath/tan.hpp b/contrib/python/pythran/pythran/pythonic/cmath/tan.hpp
new file mode 100644
index 00000000000..23052a4a6e0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/cmath/tan.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_CMATH_TAN_HPP
+#define PYTHONIC_CMATH_TAN_HPP
+
+#include "pythonic/include/cmath/tan.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/cmath/tanh.hpp b/contrib/python/pythran/pythran/pythonic/cmath/tanh.hpp
new file mode 100644
index 00000000000..b81d76e718a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/cmath/tanh.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_CMATH_TANH_HPP
+#define PYTHONIC_CMATH_TANH_HPP
+
+#include "pythonic/include/cmath/tanh.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/functools/partial.hpp b/contrib/python/pythran/pythran/pythonic/functools/partial.hpp
new file mode 100644
index 00000000000..d6ab8bdabe2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/functools/partial.hpp
@@ -0,0 +1,53 @@
+#ifndef PYTHONIC_FUNCTOOLS_PARTIAL_HPP
+#define PYTHONIC_FUNCTOOLS_PARTIAL_HPP
+
+#include "pythonic/include/functools/partial.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/seq.hpp"
+
+#include <utility>
+
+PYTHONIC_NS_BEGIN
+
+namespace functools
+{
+
+ namespace details
+ {
+
+ template <typename... ClosureTypes>
+ task<ClosureTypes...>::task()
+ : closure()
+ {
+ }
+
+ template <typename... ClosureTypes>
+ task<ClosureTypes...>::task(ClosureTypes const &... types)
+ : closure(types...)
+ {
+ }
+
+ template <typename... ClosureTypes>
+ template <typename... Types>
+ auto task<ClosureTypes...>::operator()(Types &&... types) const -> decltype(
+ this->call(utils::make_index_sequence<sizeof...(ClosureTypes)-1>(),
+ std::forward<Types>(types)...))
+ {
+ return call(utils::make_index_sequence<sizeof...(ClosureTypes)-1>(),
+ std::forward<Types>(types)...);
+ }
+ }
+
+ template <typename... Types>
+ // remove references as closure capture the env by copy
+ details::task<typename std::remove_cv<
+ typename std::remove_reference<Types>::type>::type...>
+ partial(Types &&... types)
+ {
+ return {std::forward<Types>(types)...};
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/functools/reduce.hpp b/contrib/python/pythran/pythran/pythonic/functools/reduce.hpp
new file mode 100644
index 00000000000..3d0cdff245a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/functools/reduce.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_FUNCTOOLS_REDUCE_HPP
+#define PYTHONIC_FUNCTOOLS_REDUCE_HPP
+
+#include "pythonic/include/functools/reduce.hpp"
+#include "pythonic/builtins/reduce.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/__dispatch__/clear.hpp b/contrib/python/pythran/pythran/pythonic/include/__dispatch__/clear.hpp
new file mode 100644
index 00000000000..ae78da378ba
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/__dispatch__/clear.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_DISPATCH_CLEAR_HPP
+#define PYTHONIC_INCLUDE_DISPATCH_CLEAR_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace __dispatch__
+{
+ template <class Any>
+ auto clear(Any &&any) -> decltype(any.clear())
+ {
+ return any.clear();
+ }
+
+ DEFINE_FUNCTOR(pythonic::__dispatch__, clear);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/__dispatch__/conjugate.hpp b/contrib/python/pythran/pythran/pythonic/include/__dispatch__/conjugate.hpp
new file mode 100644
index 00000000000..869cb55762e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/__dispatch__/conjugate.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_DISPATCH_CONJUGATE_HPP
+#define PYTHONIC_INCLUDE_DISPATCH_CONJUGATE_HPP
+
+#include "pythonic/include/numpy/conjugate.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace __dispatch__
+{
+ template <class Any>
+ auto conjugate(Any const &any) -> decltype(numpy::functor::conjugate{}(any));
+
+ DEFINE_FUNCTOR(pythonic::__dispatch__, conjugate);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/__dispatch__/copy.hpp b/contrib/python/pythran/pythran/pythonic/include/__dispatch__/copy.hpp
new file mode 100644
index 00000000000..04819e9477a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/__dispatch__/copy.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_DISPATCH_COPY_HPP
+#define PYTHONIC_INCLUDE_DISPATCH_COPY_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace __dispatch__
+{
+ template <class Any>
+ auto copy(Any const &any) -> decltype(any.copy());
+
+ DEFINE_FUNCTOR(pythonic::__dispatch__, copy);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/__dispatch__/count.hpp b/contrib/python/pythran/pythran/pythonic/include/__dispatch__/count.hpp
new file mode 100644
index 00000000000..0fe42b94e7b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/__dispatch__/count.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_DISPATCH_COUNT_HPP
+#define PYTHONIC_INCLUDE_DISPATCH_COUNT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace __dispatch__
+{
+ template <class Any, class Value>
+ auto count(Any &&any, Value &&value)
+ -> decltype(any.count(std::forward<Value>(value)));
+
+ DEFINE_FUNCTOR(pythonic::__dispatch__, count);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/__dispatch__/index.hpp b/contrib/python/pythran/pythran/pythonic/include/__dispatch__/index.hpp
new file mode 100644
index 00000000000..c658f749418
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/__dispatch__/index.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_DISPATCH_INDEX_HPP
+#define PYTHONIC_INCLUDE_DISPATCH_INDEX_HPP
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/include/operator_/indexOf.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace __dispatch__
+{
+ USING_FUNCTOR(index, pythonic::operator_::functor::indexOf);
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/__dispatch__/pop.hpp b/contrib/python/pythran/pythran/pythonic/include/__dispatch__/pop.hpp
new file mode 100644
index 00000000000..8a44bfe1a57
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/__dispatch__/pop.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_DISPATCH_POP_HPP
+#define PYTHONIC_INCLUDE_DISPATCH_POP_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace __dispatch__
+{
+ template <class Any, class... Arg0>
+ auto pop(Any &&any, Arg0 &&... arg0)
+ -> decltype(any.pop(std::forward<Arg0>(arg0)...));
+
+ DEFINE_FUNCTOR(pythonic::__dispatch__, pop);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/__dispatch__/remove.hpp b/contrib/python/pythran/pythran/pythonic/include/__dispatch__/remove.hpp
new file mode 100644
index 00000000000..4b78c24603e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/__dispatch__/remove.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_DISPATCH_REMOVE_HPP
+#define PYTHONIC_INCLUDE_DISPATCH_REMOVE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace __dispatch__
+{
+ template <class Any, class Arg0>
+ auto remove(Any &any, Arg0 const &arg0) -> decltype(any.remove(arg0));
+
+ DEFINE_FUNCTOR(pythonic::__dispatch__, remove);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/__dispatch__/sort.hpp b/contrib/python/pythran/pythran/pythonic/include/__dispatch__/sort.hpp
new file mode 100644
index 00000000000..e2dc8fe4c0c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/__dispatch__/sort.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_DISPATCH_SORT_HPP
+#define PYTHONIC_INCLUDE_DISPATCH_SORT_HPP
+
+#include "pythonic/include/builtins/list/sort.hpp"
+#include "pythonic/include/numpy/sort.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace __dispatch__
+{
+
+ template <class T, class... Args>
+ auto sort(types::list<T> &l, Args &&... args)
+ -> decltype(pythonic::builtins::list::sort(l,
+ std::forward<Args>(args)...));
+ template <class T, class... Args>
+ auto sort(types::list<T> &&l, Args &&... args)
+ -> decltype(pythonic::builtins::list::sort(std::move(l),
+ std::forward<Args>(args)...));
+ template <class Any, class... Args>
+ types::none_type sort(Any &&any, Args &&... args);
+
+ DEFINE_FUNCTOR(pythonic::__dispatch__, sort);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/__dispatch__/update.hpp b/contrib/python/pythran/pythran/pythonic/include/__dispatch__/update.hpp
new file mode 100644
index 00000000000..e7ed9dd06bf
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/__dispatch__/update.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_DISPATCH_UPDATE_HPP
+#define PYTHONIC_INCLUDE_DISPATCH_UPDATE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace __dispatch__
+{
+
+ template <class Any, class... Arg0>
+ auto update(Any &&any, Arg0 &&... arg0)
+ -> decltype(any.update(std::forward<Arg0>(arg0)...));
+
+ DEFINE_FUNCTOR(pythonic::__dispatch__, update);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/bisect/bisect.hpp b/contrib/python/pythran/pythran/pythonic/include/bisect/bisect.hpp
new file mode 100644
index 00000000000..8eb3e9fda50
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/bisect/bisect.hpp
@@ -0,0 +1,33 @@
+#ifndef PYTHONIC_INCLUDE_BISECT_BISECT_HPP
+#define PYTHONIC_INCLUDE_BISECT_BISECT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+#include <algorithm>
+
+PYTHONIC_NS_BEGIN
+
+namespace bisect
+{
+ namespace details
+ {
+ template <class X, class A>
+ using bisect_fun =
+ decltype(std::upper_bound<typename X::const_iterator, A>);
+ }
+
+ template <class X, class A>
+ long bisect(X const &x, A const &a, long lo = 0,
+ details::bisect_fun<X, A> const &fun =
+ std::upper_bound<typename X::const_iterator, A>);
+
+ template <class X, class A>
+ long bisect(X const &x, A const &a, long lo, long hi,
+ details::bisect_fun<X, A> const &fun =
+ std::upper_bound<typename X::const_iterator, A>);
+
+ DEFINE_FUNCTOR(pythonic::bisect, bisect);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/bisect/bisect_left.hpp b/contrib/python/pythran/pythran/pythonic/include/bisect/bisect_left.hpp
new file mode 100644
index 00000000000..0953aa3e4b6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/bisect/bisect_left.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_BISECT_BISECTLEFT_HPP
+#define PYTHONIC_INCLUDE_BISECT_BISECTLEFT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace bisect
+{
+ template <class X, class A>
+ long bisect_left(X const &x, A const &a, long lo = 0);
+
+ template <class X, class A>
+ long bisect_left(X const &x, A const &a, long lo, long hi);
+
+ DEFINE_FUNCTOR(pythonic::bisect, bisect_left);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/bisect/bisect_right.hpp b/contrib/python/pythran/pythran/pythonic/include/bisect/bisect_right.hpp
new file mode 100644
index 00000000000..c4d0d479e4a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/bisect/bisect_right.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_BISECT_BISECTRIGHT_HPP
+#define PYTHONIC_INCLUDE_BISECT_BISECTRIGHT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace bisect
+{
+ template <class X, class A>
+ long bisect_right(X const &x, A const &a, long lo = 0);
+
+ template <class X, class A>
+ long bisect_right(X const &x, A const &a, long lo, long hi);
+
+ DEFINE_FUNCTOR(pythonic::bisect, bisect_right);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/ArithmeticError.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/ArithmeticError.hpp
new file mode 100644
index 00000000000..e89270eb2ce
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/ArithmeticError.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_ARITHMETICERROR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_ARITHMETICERROR_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(ArithmeticError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/AssertionError.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/AssertionError.hpp
new file mode 100644
index 00000000000..fe45a706126
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/AssertionError.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_ASSERTIONERROR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_ASSERTIONERROR_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(AssertionError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/AttributeError.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/AttributeError.hpp
new file mode 100644
index 00000000000..dfec7a06e9c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/AttributeError.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_ATTRIBUTEERROR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_ATTRIBUTEERROR_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(AttributeError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/BaseException.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/BaseException.hpp
new file mode 100644
index 00000000000..3ca9d7a2775
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/BaseException.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_BASEEXCEPTION_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_BASEEXCEPTION_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(BaseException)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/BufferError.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/BufferError.hpp
new file mode 100644
index 00000000000..b1a58bddeb7
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/BufferError.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_BUFFERERROR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_BUFFERERROR_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(BufferError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/BytesWarning.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/BytesWarning.hpp
new file mode 100644
index 00000000000..61270007320
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/BytesWarning.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_BYTESWARNING_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_BYTESWARNING_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(BytesWarning)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/DeprecationWarning.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/DeprecationWarning.hpp
new file mode 100644
index 00000000000..3694993d746
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/DeprecationWarning.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_DEPRECATIONWARNING_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_DEPRECATIONWARNING_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(DeprecationWarning)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/EOFError.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/EOFError.hpp
new file mode 100644
index 00000000000..1a618a6c1be
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/EOFError.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_EOFERROR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_EOFERROR_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(EOFError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/EnvironmentError.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/EnvironmentError.hpp
new file mode 100644
index 00000000000..8951d413786
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/EnvironmentError.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_ENVIRONMENTERROR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_ENVIRONMENTERROR_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(EnvironmentError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/Exception.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/Exception.hpp
new file mode 100644
index 00000000000..ec3b9bc8d09
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/Exception.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_EXCEPTION_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_EXCEPTION_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(Exception)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/False.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/False.hpp
new file mode 100644
index 00000000000..995a659c0e9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/False.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_FALSE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_FALSE_HPP
+
+#include "pythonic/include/types/bool.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ static const bool False = false;
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/FileNotFoundError.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/FileNotFoundError.hpp
new file mode 100644
index 00000000000..0105bad0745
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/FileNotFoundError.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_FILENOTFOUNDERROR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_FILENOTFOUNDERROR_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(FileNotFoundError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/FloatingPointError.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/FloatingPointError.hpp
new file mode 100644
index 00000000000..4cc174702bf
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/FloatingPointError.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_FLOATINGPOINTERROR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_FLOATINGPOINTERROR_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(FloatingPointError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/FutureWarning.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/FutureWarning.hpp
new file mode 100644
index 00000000000..3b5b8a7083f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/FutureWarning.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_FUTUREWARNING_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_FUTUREWARNING_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(FutureWarning)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/GeneratorExit.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/GeneratorExit.hpp
new file mode 100644
index 00000000000..a3a5fb155a7
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/GeneratorExit.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_GENERATOREXIT_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_GENERATOREXIT_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(GeneratorExit)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/IOError.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/IOError.hpp
new file mode 100644
index 00000000000..5a05ae28c27
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/IOError.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_IOERROR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_IOERROR_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(IOError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/ImportError.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/ImportError.hpp
new file mode 100644
index 00000000000..006693fb584
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/ImportError.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_IMPORTERROR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_IMPORTERROR_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(ImportError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/ImportWarning.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/ImportWarning.hpp
new file mode 100644
index 00000000000..155eb2168bd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/ImportWarning.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_IMPORTWARNING_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_IMPORTWARNING_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(ImportWarning)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/IndentationError.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/IndentationError.hpp
new file mode 100644
index 00000000000..1e0c8cb542c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/IndentationError.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_INDENTATIONERROR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_INDENTATIONERROR_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(IndentationError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/IndexError.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/IndexError.hpp
new file mode 100644
index 00000000000..2e9ebb466b5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/IndexError.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_INDEXERROR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_INDEXERROR_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(IndexError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/KeyboardInterrupt.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/KeyboardInterrupt.hpp
new file mode 100644
index 00000000000..19898b7d7db
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/KeyboardInterrupt.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_KEYBOARDINTERRUPT_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_KEYBOARDINTERRUPT_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(KeyboardInterrupt)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/LookupError.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/LookupError.hpp
new file mode 100644
index 00000000000..90b729c25b4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/LookupError.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_LOOKUPERROR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_LOOKUPERROR_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(LookupError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/NameError.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/NameError.hpp
new file mode 100644
index 00000000000..0f165a9d53c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/NameError.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_NAMEERROR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_NAMEERROR_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(NameError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/OSError.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/OSError.hpp
new file mode 100644
index 00000000000..e0f090277a8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/OSError.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_OSERROR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_OSERROR_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(OSError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/OverflowError.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/OverflowError.hpp
new file mode 100644
index 00000000000..755baa2a31d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/OverflowError.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_OVERFLOWERROR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_OVERFLOWERROR_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(OverflowError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/PendingDeprecationWarning.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/PendingDeprecationWarning.hpp
new file mode 100644
index 00000000000..32bf8a00d7c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/PendingDeprecationWarning.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_PENDINGDEPRECATIONWARNING_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_PENDINGDEPRECATIONWARNING_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(PendingDeprecationWarning)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/ReferenceError.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/ReferenceError.hpp
new file mode 100644
index 00000000000..458553b1206
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/ReferenceError.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_REFERENCEERROR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_REFERENCEERROR_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(ReferenceError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/RuntimeWarning.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/RuntimeWarning.hpp
new file mode 100644
index 00000000000..7c3051cd1bb
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/RuntimeWarning.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_RUNTIMEWARNING_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_RUNTIMEWARNING_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(RuntimeWarning)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/StopIteration.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/StopIteration.hpp
new file mode 100644
index 00000000000..c13eb887f18
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/StopIteration.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_STOPITERATION_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_STOPITERATION_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(StopIteration)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/SyntaxError.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/SyntaxError.hpp
new file mode 100644
index 00000000000..bafec3ca63a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/SyntaxError.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SYNTAXERROR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SYNTAXERROR_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(SyntaxError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/SyntaxWarning.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/SyntaxWarning.hpp
new file mode 100644
index 00000000000..b3a1e2dfe2a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/SyntaxWarning.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SYNTAXWARNING_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SYNTAXWARNING_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(SyntaxWarning)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/SystemError.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/SystemError.hpp
new file mode 100644
index 00000000000..df0bb46d146
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/SystemError.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SYSTEMERROR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SYSTEMERROR_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(SystemError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/SystemExit.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/SystemExit.hpp
new file mode 100644
index 00000000000..f7190dfc197
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/SystemExit.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SYSTEMEXIT_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SYSTEMEXIT_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(SystemExit)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/TabError.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/TabError.hpp
new file mode 100644
index 00000000000..6aa0690f33f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/TabError.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_TABERROR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_TABERROR_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(TabError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/True.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/True.hpp
new file mode 100644
index 00000000000..a987a292333
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/True.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_TRUE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_TRUE_HPP
+
+#include "pythonic/include/types/bool.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ static const bool True = true;
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/TypeError.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/TypeError.hpp
new file mode 100644
index 00000000000..0da6f47f822
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/TypeError.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_TYPEERROR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_TYPEERROR_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(TypeError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/UnboundLocalError.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/UnboundLocalError.hpp
new file mode 100644
index 00000000000..0558b98fe09
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/UnboundLocalError.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_UNBOUNDLOCALERROR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_UNBOUNDLOCALERROR_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(UnboundLocalError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/UnicodeError.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/UnicodeError.hpp
new file mode 100644
index 00000000000..406392f1f22
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/UnicodeError.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_UNICODEERROR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_UNICODEERROR_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(UnicodeError)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/UnicodeWarning.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/UnicodeWarning.hpp
new file mode 100644
index 00000000000..3cc50a923a2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/UnicodeWarning.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_UNICODEWARNING_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_UNICODEWARNING_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(UnicodeWarning)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/UserWarning.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/UserWarning.hpp
new file mode 100644
index 00000000000..6d02ec7feef
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/UserWarning.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_USERWARNING_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_USERWARNING_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(UserWarning)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/Warning.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/Warning.hpp
new file mode 100644
index 00000000000..98d25fe83ce
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/Warning.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_WARNING_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_WARNING_HPP
+
+#include "pythonic/include/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ PYTHONIC_EXCEPTION_DECL(Warning)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/abs.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/abs.hpp
new file mode 100644
index 00000000000..ca927fb6226
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/abs.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_ABS_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_ABS_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/numpy/abs.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+ // FIXME np.abs accept any iterator while builtins.abs only accept
+ // numeric types && numpy.array
+ USING_FUNCTOR(abs, numpy::functor::abs);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/all.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/all.hpp
new file mode 100644
index 00000000000..e3b619e3af8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/all.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_ALL_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_ALL_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ template <class Iterable>
+ bool all(Iterable &&s);
+
+ DEFINE_FUNCTOR(pythonic::builtins, all);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/any.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/any.hpp
new file mode 100644
index 00000000000..86b3d845cd8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/any.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_ANY_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_ANY_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+ template <class Iterable>
+ bool any(Iterable &&s);
+
+ DEFINE_FUNCTOR(pythonic::builtins, any);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/assert.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/assert.hpp
new file mode 100644
index 00000000000..853ed73a4e4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/assert.hpp
@@ -0,0 +1,11 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_ASSERT_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_ASSERT_HPP
+
+#include "pythonic/include/types/str.hpp"
+
+PYTHONIC_NS_BEGIN
+void pythran_assert(bool cond);
+void pythran_assert(bool cond, types::str const &what);
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/bin.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/bin.hpp
new file mode 100644
index 00000000000..7365388c787
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/bin.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_BIN_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_BIN_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+#include "pythonic/include/types/str.hpp"
+
+#include <type_traits>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+ template <class T>
+ typename std::enable_if<std::is_scalar<T>::value, types::str>::type
+ bin(T const &v);
+
+ DEFINE_FUNCTOR(pythonic::builtins, bin);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/chr.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/chr.hpp
new file mode 100644
index 00000000000..6e30ee95908
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/chr.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_CHR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_CHR_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/str.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+ template <class T>
+ types::str chr(T const &v);
+
+ DEFINE_FUNCTOR(pythonic::builtins, chr);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/complex.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/complex.hpp
new file mode 100644
index 00000000000..7057bd3791f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/complex.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_COMPLEX_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_COMPLEX_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/complex.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace functor
+ {
+ struct complex {
+ using callable = void;
+ using type = std::complex<double>;
+ // TODO: doesn't handle string as first argument
+ type operator()(double v0 = 0, double v1 = 0) const;
+ friend std::ostream &operator<<(std::ostream &os, complex)
+ {
+ return os << "complex";
+ }
+ };
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/complex/conjugate.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/complex/conjugate.hpp
new file mode 100644
index 00000000000..dcb8d5ac329
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/complex/conjugate.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_COMPLEX_CONJUGATE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_COMPLEX_CONJUGATE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/numpy/conjugate.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace builtins
+{
+ namespace complex
+ {
+ USING_FUNCTOR(conjugate, numpy::functor::conjugate);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/dict/clear.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/dict/clear.hpp
new file mode 100644
index 00000000000..d90a2f3cf22
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/dict/clear.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_DICT_CLEAR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_DICT_CLEAR_HPP
+
+#include "pythonic/include/__dispatch__/clear.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace builtins
+{
+ namespace dict
+ {
+ USING_FUNCTOR(clear, pythonic::__dispatch__::functor::clear);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/dict/copy.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/dict/copy.hpp
new file mode 100644
index 00000000000..e0a92e31bb2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/dict/copy.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_DICT_COPY_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_DICT_COPY_HPP
+
+#include "pythonic/include/__dispatch__/copy.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace builtins
+{
+ namespace dict
+ {
+ USING_FUNCTOR(copy, pythonic::__dispatch__::functor::copy);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/dict/fromkeys.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/dict/fromkeys.hpp
new file mode 100644
index 00000000000..0bcf1ff1e86
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/dict/fromkeys.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_DICT_FROMKEYS_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_DICT_FROMKEYS_HPP
+
+#include "pythonic/include/builtins/None.hpp"
+#include "pythonic/include/types/dict.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+#include <type_traits>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace dict
+ {
+
+ template <class Iterable, class V = types::none_type>
+ types::dict<typename std::remove_reference<Iterable>::type::value_type, V>
+ fromkeys(Iterable &&iter, V const &v = builtins::None);
+
+ DEFINE_FUNCTOR(pythonic::builtins::dict, fromkeys);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/dict/get.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/dict/get.hpp
new file mode 100644
index 00000000000..01edc4b6a58
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/dict/get.hpp
@@ -0,0 +1,35 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_DICT_GET_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_DICT_GET_HPP
+
+#include "pythonic/include/types/dict.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace dict
+ {
+
+ template <class K, class V, class W, class X>
+ typename __combined<V, X>::type get(types::dict<K, V> const &d, W const &k,
+ X const &default_);
+
+ template <class K, class V, class W>
+ types::none<V> get(types::dict<K, V> const &d, W const &k);
+
+ template <class W, class X>
+ X get(types::empty_dict const &, W const &, X const &default_);
+
+ // For typing only
+ template <class T, class I, class J>
+ typename __combined<T, J>::type get(::dict_container<T>, I, J);
+
+ DEFINE_FUNCTOR(pythonic::builtins::dict, get);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/dict/items.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/dict/items.hpp
new file mode 100644
index 00000000000..21e47d0e6ee
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/dict/items.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_DICT_ITEMS_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_DICT_ITEMS_HPP
+
+#include "pythonic/include/types/dict.hpp"
+#include "pythonic/include/types/list.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+#include <tuple>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace dict
+ {
+
+ template <class D>
+ auto items(D &&d) -> decltype(std::forward<D>(d).items());
+
+ DEFINE_FUNCTOR(pythonic::builtins::dict, items);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/dict/keys.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/dict/keys.hpp
new file mode 100644
index 00000000000..f0dbba54520
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/dict/keys.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_DICT_KEYS_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_DICT_KEYS_HPP
+
+#include "pythonic/include/types/dict.hpp"
+#include "pythonic/include/types/list.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace dict
+ {
+
+ template <class D>
+ auto keys(D &&d) -> decltype(std::forward<D>(d).keys());
+
+ DEFINE_FUNCTOR(pythonic::builtins::dict, keys);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/dict/pop.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/dict/pop.hpp
new file mode 100644
index 00000000000..7d0562c7899
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/dict/pop.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_DICT_POP_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_DICT_POP_HPP
+
+#include "pythonic/include/__dispatch__/pop.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace builtins
+{
+ namespace dict
+ {
+ USING_FUNCTOR(pop, pythonic::__dispatch__::functor::pop);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/dict/popitem.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/dict/popitem.hpp
new file mode 100644
index 00000000000..5f12f97b596
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/dict/popitem.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_DICT_POPITEM_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_DICT_POPITEM_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/dict.hpp"
+
+#include <tuple>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace dict
+ {
+
+ template <class D>
+ auto popitem(D &&d) -> decltype(std::forward<D>(d).popitem());
+
+ DEFINE_FUNCTOR(pythonic::builtins::dict, popitem);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/dict/setdefault.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/dict/setdefault.hpp
new file mode 100644
index 00000000000..e14b8221c08
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/dict/setdefault.hpp
@@ -0,0 +1,32 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_DICT_SETDEFAULT_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_DICT_SETDEFAULT_HPP
+
+#include "pythonic/include/types/dict.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace dict
+ {
+
+ template <class K, class V, class W, class X>
+ V &setdefault(types::dict<K, V> &d, W const &k, X const &default_);
+
+ template <class K, class V, class W>
+ types::none<V> setdefault(types::dict<K, V> &d, W const &k);
+
+ template <class K, class V, class W, class X>
+ V setdefault(types::dict<K, V> &&d, W const &k, X const &default_);
+
+ template <class K, class V, class W>
+ types::none<V> setdefault(types::dict<K, V> &&d, W const &k);
+
+ DEFINE_FUNCTOR(pythonic::builtins::dict, setdefault);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/dict/update.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/dict/update.hpp
new file mode 100644
index 00000000000..8d6990a90f7
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/dict/update.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_DICT_UPDATE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_DICT_UPDATE_HPP
+
+#include "pythonic/include/__dispatch__/update.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace builtins
+{
+ namespace dict
+ {
+ USING_FUNCTOR(update, pythonic::__dispatch__::functor::update);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/dict/values.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/dict/values.hpp
new file mode 100644
index 00000000000..26030f7f09b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/dict/values.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_DICT_VALUES_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_DICT_VALUES_HPP
+
+#include "pythonic/include/types/dict.hpp"
+#include "pythonic/include/types/list.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace dict
+ {
+ template <class D>
+ auto values(D &&d) -> decltype(std::forward<D>(d).values());
+
+ DEFINE_FUNCTOR(pythonic::builtins::dict, values);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/divmod.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/divmod.hpp
new file mode 100644
index 00000000000..c6933382676
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/divmod.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_DIVMOD_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_DIVMOD_HPP
+
+#include "pythonic/include/types/tuple.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ template <class T0, class T1>
+ auto divmod(T0 const &t0, T1 const &t1) // other types are left over
+ -> decltype(types::make_tuple(t0 / t1, t0 % t1));
+
+ DEFINE_FUNCTOR(pythonic::builtins, divmod);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/enumerate.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/enumerate.hpp
new file mode 100644
index 00000000000..e2e10a8e412
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/enumerate.hpp
@@ -0,0 +1,75 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_ENUMERATE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_ENUMERATE_HPP
+
+#include "pythonic/include/types/tuple.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+#include <iterator>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace details
+ {
+ // FIXME return value may be a type::make_tuple
+ template <class Iterator>
+ using enumerate_iterator_base = std::iterator<
+ typename std::iterator_traits<Iterator>::iterator_category,
+ types::make_tuple_t<
+ long, typename std::iterator_traits<Iterator>::value_type>>;
+
+ template <class Iterator>
+ struct enumerate_iterator : public enumerate_iterator_base<Iterator> {
+ long value;
+ Iterator iter;
+ enumerate_iterator();
+ enumerate_iterator(Iterator const &iter, long first);
+ typename enumerate_iterator_base<Iterator>::value_type operator*() const
+ {
+ return types::make_tuple(value, *iter);
+ }
+ enumerate_iterator &operator++()
+ {
+ ++value, ++iter;
+ return *this;
+ }
+ enumerate_iterator &operator+=(long n);
+ bool operator!=(enumerate_iterator const &other) const;
+ bool operator<(enumerate_iterator const &other) const;
+ long operator-(enumerate_iterator const &other) const;
+ bool operator==(enumerate_iterator const &it) const;
+ };
+
+ template <class Iterable>
+ struct enumerate
+ : private Iterable, /* to hold a reference on the iterable */
+ public enumerate_iterator<
+ typename Iterable::iterator> /* to be compatible with
+ builtins.next*/
+ {
+ using iterator = enumerate_iterator<typename Iterable::iterator>;
+ using iterator::operator*;
+ using value_type = typename iterator::value_type;
+
+ iterator end_iter;
+
+ enumerate();
+ enumerate(Iterable seq, long first);
+ iterator &begin();
+ iterator const &begin() const;
+ iterator end() const;
+ };
+ } // namespace details
+
+ template <class Iterable>
+ details::enumerate<typename std::remove_cv<
+ typename std::remove_reference<Iterable>::type>::type>
+ enumerate(Iterable &&seq, long first = 0L);
+
+ DEFINE_FUNCTOR(pythonic::builtins, enumerate);
+} // namespace builtins
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/file.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/file.hpp
new file mode 100644
index 00000000000..ac84be64d4f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/file.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_FILE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_FILE_HPP
+
+#include "pythonic/include/types/file.hpp"
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace anonymous
+ {
+ types::file file(types::str const &filename,
+ types::str const &strmode = "r");
+ }
+
+ DEFINE_FUNCTOR(pythonic::builtins::anonymous, file);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/file/close.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/file/close.hpp
new file mode 100644
index 00000000000..106b3d0baae
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/file/close.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_FILE_CLOSE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_FILE_CLOSE_HPP
+
+#include "pythonic/include/types/file.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ void close(types::file &f);
+ void close(types::file &&f);
+
+ DEFINE_FUNCTOR(pythonic::builtins::file, close);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/file/fileno.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/file/fileno.hpp
new file mode 100644
index 00000000000..db8c9c055e6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/file/fileno.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_FILE_FILENO_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_FILE_FILENO_HPP
+
+#include "pythonic/include/types/file.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ long fileno(types::file const &f);
+
+ DEFINE_FUNCTOR(pythonic::builtins::file, fileno);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/file/flush.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/file/flush.hpp
new file mode 100644
index 00000000000..e0d2b3a2403
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/file/flush.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_FILE_FLUSH_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_FILE_FLUSH_HPP
+
+#include "pythonic/include/types/file.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ void flush(types::file &f);
+ void flush(types::file &&f);
+
+ DEFINE_FUNCTOR(pythonic::builtins::file, flush);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/file/isatty.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/file/isatty.hpp
new file mode 100644
index 00000000000..87bfb137597
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/file/isatty.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_FILE_ISATTY_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_FILE_ISATTY_HPP
+
+#include "pythonic/include/types/file.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ bool isatty(types::file const &f);
+
+ DEFINE_FUNCTOR(pythonic::builtins::file, isatty);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/file/next.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/file/next.hpp
new file mode 100644
index 00000000000..1378f872d7f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/file/next.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_FILE_NEXT_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_FILE_NEXT_HPP
+
+#include "pythonic/include/__dispatch__/next.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace builtins
+{
+ namespace file
+ {
+ USING_FUNCTOR(next, pythonic::__dispatch__::functor::next);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/file/read.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/file/read.hpp
new file mode 100644
index 00000000000..aeaa1f3ab2a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/file/read.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_FILE_READ_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_FILE_READ_HPP
+
+#include "pythonic/include/types/file.hpp"
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ types::str read(types::file &f, long size = -1);
+ types::str read(types::file &&f, long size = -1);
+
+ DEFINE_FUNCTOR(pythonic::builtins::file, read);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/file/readline.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/file/readline.hpp
new file mode 100644
index 00000000000..31abcc98fef
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/file/readline.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_FILE_READLINE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_FILE_READLINE_HPP
+
+#include "pythonic/include/types/file.hpp"
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ types::str readline(types::file &f, long size = -1);
+ types::str readline(types::file &&f, long size = -1);
+
+ DEFINE_FUNCTOR(pythonic::builtins::file, readline);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/file/readlines.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/file/readlines.hpp
new file mode 100644
index 00000000000..32dea082d94
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/file/readlines.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_FILE_READLINES_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_FILE_READLINES_HPP
+
+#include "pythonic/include/types/file.hpp"
+#include "pythonic/include/types/list.hpp"
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ template <class F>
+ types::list<types::str> readlines(F &&f);
+ template <class F>
+ types::list<types::str> readlines(F &&f, long sizehint);
+
+ DEFINE_FUNCTOR(pythonic::builtins::file, readlines);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/file/seek.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/file/seek.hpp
new file mode 100644
index 00000000000..40f4202a5cc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/file/seek.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_FILE_SEEK_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_FILE_SEEK_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/file.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ void seek(types::file &f, long offset);
+ void seek(types::file &&f, long offset);
+ void seek(types::file &f, long offset, long whence);
+ void seek(types::file &&f, long offset, long whence);
+
+ DEFINE_FUNCTOR(pythonic::builtins::file, seek);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/file/tell.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/file/tell.hpp
new file mode 100644
index 00000000000..a9f623d3dcd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/file/tell.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_FILE_TELL_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_FILE_TELL_HPP
+
+#include "pythonic/include/types/file.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ long tell(types::file const &f);
+
+ DEFINE_FUNCTOR(pythonic::builtins::file, tell);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/file/truncate.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/file/truncate.hpp
new file mode 100644
index 00000000000..72782386998
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/file/truncate.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_FILE_TRUNCATE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_FILE_TRUNCATE_HPP
+
+#include "pythonic/include/types/file.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ void truncate(types::file &f);
+ void truncate(types::file &&f);
+ void truncate(types::file &f, long size);
+ void truncate(types::file &&f, long size);
+
+ DEFINE_FUNCTOR(pythonic::builtins::file, truncate);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/file/write.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/file/write.hpp
new file mode 100644
index 00000000000..66f09cc73e4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/file/write.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_FILE_WRITE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_FILE_WRITE_HPP
+
+#include "pythonic/include/types/file.hpp"
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ long write(types::file &f, types::str const &str);
+ long write(types::file &&f, types::str const &str);
+
+ DEFINE_FUNCTOR(pythonic::builtins::file, write);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/file/writelines.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/file/writelines.hpp
new file mode 100644
index 00000000000..f98dfc14825
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/file/writelines.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_FILE_WRITELINES_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_FILE_WRITELINES_HPP
+
+#include "pythonic/include/types/file.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace file
+ {
+
+ template <class F, class T>
+ void writelines(F &&f, T const &sequence);
+
+ DEFINE_FUNCTOR(pythonic::builtins::file, writelines);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/filter.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/filter.hpp
new file mode 100644
index 00000000000..80081481fa7
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/filter.hpp
@@ -0,0 +1,91 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_FILTER_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_FILTER_HPP
+
+#include "pythonic/include/itertools/common.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/iterator.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace details
+ {
+
+ template <typename Operator, typename List0>
+ struct filter_iterator
+ : std::iterator<std::forward_iterator_tag, typename List0::value_type> {
+ using sequence_type = typename std::remove_cv<
+ typename std::remove_reference<List0>::type>::type;
+
+ Operator op;
+ typename List0::iterator iter;
+ // FIXME : iter_end should be const because filter should be evaluate
+ // only once. Some tests doesn't work with it for now because of
+ // uncorrect itertools.product implementation
+ typename List0::iterator iter_end;
+
+ bool test_filter(std::true_type);
+ bool test_filter(std::false_type);
+
+ filter_iterator() = default;
+ filter_iterator(Operator _op, List0 &_seq);
+ filter_iterator(itertools::npos, Operator _op, List0 &_seq);
+
+ typename List0::value_type operator*() const;
+
+ filter_iterator &operator++();
+ void next_value();
+
+ bool operator==(filter_iterator const &other) const;
+ bool operator!=(filter_iterator const &other) const;
+ bool operator<(filter_iterator const &other) const;
+ };
+
+ // Inherit from iterator_reminder to keep a reference on the iterator
+ // and avoid a dangling reference
+ // FIXME: It would be better to have a copy only if needed but Pythran
+ // typing is not good enough for this as arguments have
+ // remove_cv/remove_ref
+ template <typename Operator, typename List0>
+ struct filter : utils::iterator_reminder<false, List0>,
+ filter_iterator<Operator, List0> {
+
+ using value_type = typename List0::value_type;
+ using iterator = filter_iterator<Operator, List0>;
+
+ iterator end_iter;
+
+ filter() = default;
+ filter(Operator _op, List0 const &_seq);
+
+ iterator &begin();
+ iterator const &begin() const;
+ iterator const &end() const;
+ };
+ } // namespace details
+
+ template <typename Operator, typename List0>
+ details::filter<typename std::remove_cv<
+ typename std::remove_reference<Operator>::type>::type,
+ typename std::remove_cv<
+ typename std::remove_reference<List0>::type>::type>
+ filter(Operator &&_op, List0 &&_seq);
+
+ DEFINE_FUNCTOR(pythonic::builtins, filter);
+} // namespace builtins
+PYTHONIC_NS_END
+
+/* type inference stuff {*/
+#include "pythonic/include/types/combined.hpp"
+
+template <class E, class Op, class T>
+struct __combined<E, pythonic::builtins::details::filter<Op, T>> {
+ using type =
+ typename __combined<E, container<typename pythonic::builtins::details::
+ filter<Op, T>::value_type>>::type;
+};
+/* } */
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/float_/is_integer.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/float_/is_integer.hpp
new file mode 100644
index 00000000000..cfc14f7e8c0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/float_/is_integer.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_FLOAT_ISINTEGER_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_FLOAT_ISINTEGER_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace float_
+ {
+
+ bool is_integer(double d);
+
+ DEFINE_FUNCTOR(pythonic::builtins::float_, is_integer);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/hex.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/hex.hpp
new file mode 100644
index 00000000000..5d5acb13fc8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/hex.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_HEX_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_HEX_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/str.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ template <class T>
+ types::str hex(T const &v);
+
+ DEFINE_FUNCTOR(pythonic::builtins, hex);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/isinstance.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/isinstance.hpp
new file mode 100644
index 00000000000..8a25f0f33cc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/isinstance.hpp
@@ -0,0 +1,63 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_ISINSTANCE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_ISINSTANCE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/builtins/pythran/is_none.hpp"
+#include "pythonic/include/utils/meta.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace types
+{
+ class str;
+
+ template <class Ty0, class Ty1>
+ struct isinstance
+ : std::conditional<std::is_same<Ty0, Ty1>::value, true_type, false_type> {
+ };
+
+ // some specialization
+
+ template <>
+ struct isinstance<char const *, str> {
+ using type = true_type;
+ };
+ template <>
+ struct isinstance<str, char const *> {
+ using type = true_type;
+ };
+}
+
+namespace builtins
+{
+ namespace details
+ {
+ template <class Obj, class Cls>
+ struct isinstance {
+ using type = typename types::isinstance<
+ Obj,
+ typename std::decay<decltype(std::declval<Cls>()())>::type>::type;
+ };
+
+ template <class Obj, class... Clss>
+ struct isinstance<Obj, std::tuple<Clss...>> {
+ using type = typename std::conditional<
+ utils::any_of<
+ std::is_same<typename types::isinstance<
+ Obj, typename std::decay<decltype(
+ std::declval<Clss>()())>::type>::type,
+ types::true_type>::value...>::value,
+ types::true_type, types::false_type>::type;
+ };
+ }
+
+ template <class Obj, class Cls>
+ typename details::isinstance<Obj, Cls>::type isinstance(Obj, Cls)
+ {
+ return {};
+ }
+
+ DEFINE_FUNCTOR(pythonic::builtins, isinstance);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/iter.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/iter.hpp
new file mode 100644
index 00000000000..1e3dc07c495
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/iter.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_ITER_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_ITER_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace details
+ {
+ template <class T>
+ struct iter : T::iterator {
+ using iterator = typename T::iterator;
+
+ iterator _end;
+ T data;
+
+ iter();
+ iter(T data);
+ iterator &begin();
+ iterator const &begin() const;
+ iterator const &end() const;
+ };
+ }
+
+ template <class T>
+ details::iter<
+ typename std::remove_cv<typename std::remove_reference<T>::type>::type>
+ iter(T &&t);
+
+ DEFINE_FUNCTOR(pythonic::builtins, iter);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/list/count.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/list/count.hpp
new file mode 100644
index 00000000000..b8e3707b906
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/list/count.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_LIST_COUNT_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_LIST_COUNT_HPP
+
+#include "pythonic/include/__dispatch__/count.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace list
+ {
+ USING_FUNCTOR(count, pythonic::__dispatch__::functor::count);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/list/extend.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/list/extend.hpp
new file mode 100644
index 00000000000..8c071ca1aee
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/list/extend.hpp
@@ -0,0 +1,32 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_LIST_EXTEND_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_LIST_EXTEND_HPP
+
+#include "pythonic/include/types/list.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace list
+ {
+
+ template <class T0, class T1>
+ typename std::enable_if<
+ !std::is_same<typename std::decay<T0>::type, types::empty_list>::value,
+ types::none_type>::type
+ extend(T0 &&seq, T1 const &add);
+
+ template <class T0, class T1>
+ typename std::enable_if<
+ std::is_same<typename std::decay<T0>::type, types::empty_list>::value,
+ types::none_type>::type
+ extend(T0 &&seq, T1 const &add);
+
+ DEFINE_FUNCTOR(pythonic::builtins::list, extend);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/list/insert.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/list/insert.hpp
new file mode 100644
index 00000000000..58bfb6a686c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/list/insert.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_LIST_INSERT_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_LIST_INSERT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/list.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace list
+ {
+
+ template <class T, class F>
+ types::none_type insert(types::list<T> &seq, long n, F &&value);
+
+ DEFINE_FUNCTOR(pythonic::builtins::list, insert);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/list/pop.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/list/pop.hpp
new file mode 100644
index 00000000000..9ac28a6d27a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/list/pop.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_LIST_POP_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_LIST_POP_HPP
+
+#include "pythonic/include/__dispatch__/pop.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace list
+ {
+ USING_FUNCTOR(pop, pythonic::__dispatch__::functor::pop);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/list/remove.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/list/remove.hpp
new file mode 100644
index 00000000000..8fd44c85b35
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/list/remove.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_LIST_REMOVE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_LIST_REMOVE_HPP
+
+#include "pythonic/include/__dispatch__/remove.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace list
+ {
+ USING_FUNCTOR(remove, pythonic::__dispatch__::functor::remove);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/list/reverse.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/list/reverse.hpp
new file mode 100644
index 00000000000..edc2c523706
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/list/reverse.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_LIST_REVERSE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_LIST_REVERSE_HPP
+
+#include "pythonic/include/types/list.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace list
+ {
+
+ template <class T>
+ types::none_type reverse(types::list<T> &seq);
+
+ DEFINE_FUNCTOR(pythonic::builtins::list, reverse);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/list/sort.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/list/sort.hpp
new file mode 100644
index 00000000000..4f92e8f0334
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/list/sort.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_LIST_SORT_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_LIST_SORT_HPP
+
+#include "pythonic/include/types/list.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace list
+ {
+
+ template <class T>
+ types::none_type sort(types::list<T> &seq);
+
+ template <class T, class K>
+ types::none_type sort(types::list<T> &seq, K key);
+
+ DEFINE_FUNCTOR(pythonic::builtins::list, sort);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/map.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/map.hpp
new file mode 100644
index 00000000000..5e0912eb599
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/map.hpp
@@ -0,0 +1,151 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_MAP_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_MAP_HPP
+
+#include "pythonic/include/itertools/common.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/tuple.hpp"
+#include "pythonic/include/utils/int_.hpp"
+#include "pythonic/include/utils/iterator.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/seq.hpp"
+
+#include <utility>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace details
+ {
+
+ template <class Operator, class... Iters>
+ struct map_res {
+ using type = decltype(
+ std::declval<Operator>()(std::declval<typename std::iterator_traits<
+ typename Iters::iterator>::value_type>()...));
+ };
+
+ template <class... Iters>
+ struct map_res<types::none_type, Iters...> {
+ using type =
+ decltype(types::make_tuple(std::declval<typename std::iterator_traits<
+ typename Iters::iterator>::value_type>()...));
+ };
+
+ template <typename Operator, typename... Iters>
+ struct map_iterator
+ : std::iterator<
+ typename utils::iterator_min<typename Iters::iterator...>::type,
+ typename map_res<Operator, Iters...>::type> {
+ std::tuple<typename Iters::iterator...> it;
+ Operator _op;
+
+ map_iterator() = default;
+ template <size_t... I>
+ map_iterator(Operator const &_op, std::tuple<Iters...> &_iters,
+ utils::index_sequence<I...>);
+ template <size_t... I>
+ map_iterator(itertools::npos, Operator const &_op,
+ std::tuple<Iters...> &_iters, utils::index_sequence<I...>);
+
+ typename map_res<Operator, Iters...>::type operator*() const;
+ map_iterator &operator++();
+ map_iterator &operator+=(long i);
+ map_iterator operator+(long i) const;
+ bool operator==(map_iterator const &other) const;
+ bool operator!=(map_iterator const &other) const;
+ bool operator<(map_iterator const &other) const;
+ long operator-(map_iterator const &other) const;
+
+ private:
+ template <size_t N>
+ long min_len(map_iterator<Operator, Iters...> const &other,
+ utils::int_<N>) const;
+ long min_len(map_iterator<Operator, Iters...> const &other,
+ utils::int_<0>) const;
+
+ template <size_t N>
+ bool equal(map_iterator const &other, utils::int_<N>) const;
+ bool equal(map_iterator const &other, utils::int_<0>) const;
+
+ template <size_t I>
+ void advance(long i, utils::int_<I>);
+ void advance(long i, utils::int_<0>);
+
+ template <size_t... I>
+ void next(utils::index_sequence<I...>);
+
+ template <size_t... I>
+ typename map_res<Operator, Iters...>::type
+ get_value(utils::index_sequence<I...>, std::true_type) const;
+ template <size_t... I>
+ typename map_res<Operator, Iters...>::type
+ get_value(utils::index_sequence<I...>, std::false_type) const;
+ };
+
+ template <typename Operator, typename... Iters>
+ struct map : utils::iterator_reminder<true, Iters...>,
+ map_iterator<Operator, Iters...> {
+ using iterator = map_iterator<Operator, Iters...>;
+ using value_type = typename iterator::value_type;
+ using dtype = typename types::dtype_of<value_type>::type;
+ static constexpr long value =
+ 1 + utils::nested_container_depth<value_type>::value;
+
+ iterator end_iter;
+
+ map() = default;
+ // Use an extra template to enable forwarding
+ template <class... Types>
+ map(Operator const &_op, Types &&... _iters);
+
+ iterator &begin();
+ iterator const &begin() const;
+ iterator const &end() const;
+ };
+ }
+
+ template <typename Operator, typename... Iter>
+ auto map(Operator &&_op, Iter &&... iters) -> details::map<
+ typename std::remove_cv<
+ typename std::remove_reference<Operator>::type>::type,
+ typename types::iterator<typename std::remove_cv<
+ typename std::remove_reference<Iter>::type>::type>::type...>;
+
+ DEFINE_FUNCTOR(pythonic::builtins, map);
+}
+
+namespace types
+{
+
+ template <class Op, class Iter>
+ struct len_of<pythonic::builtins::details::map<Op, Iter>> {
+ static constexpr long value = len_of<typename std::remove_cv<
+ typename std::remove_reference<Iter>::type>::type>::value;
+ };
+
+ template <class Op, class I0, class I1, class... Iter>
+ struct len_of<pythonic::builtins::details::map<Op, I0, I1, Iter...>> {
+ static constexpr long _head = len_of<typename std::remove_cv<
+ typename std::remove_reference<I0>::type>::type>::value;
+ static constexpr long _tail =
+ len_of<pythonic::builtins::details::map<Op, I1, Iter...>>::value;
+ // take the minimal value. If one is negative, it will be automatically
+ // selected
+ static constexpr long value = (_head < _tail ? _head : _tail);
+ };
+}
+PYTHONIC_NS_END
+
+/* type inference stuff {*/
+#include "pythonic/include/types/combined.hpp"
+
+template <class E, class Op, class... Iter>
+struct __combined<E, pythonic::builtins::details::map<Op, Iter...>> {
+ using type =
+ typename __combined<E, container<typename pythonic::builtins::details::
+ map<Op, Iter...>::value_type>>::type;
+};
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/next.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/next.hpp
new file mode 100644
index 00000000000..abea2e5ee39
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/next.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_NEXT_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_NEXT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+#include <utility>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ template <class T>
+ auto next(T &&y) -> decltype(*y);
+
+ DEFINE_FUNCTOR(pythonic::builtins, next);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/oct.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/oct.hpp
new file mode 100644
index 00000000000..af52c36a3e2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/oct.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_OCT_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_OCT_HPP
+
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+ template <class T>
+ types::str oct(T const &v);
+
+ DEFINE_FUNCTOR(pythonic::builtins, oct);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/open.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/open.hpp
new file mode 100644
index 00000000000..126985be040
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/open.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_OPEN_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_OPEN_HPP
+
+#include "pythonic/include/types/file.hpp"
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ types::file open(types::str const &filename, types::str const &strmode = "r");
+
+ DEFINE_FUNCTOR(pythonic::builtins, open);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/ord.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/ord.hpp
new file mode 100644
index 00000000000..d9658b94ae3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/ord.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_ORD_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_ORD_HPP
+
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+ long ord(types::str const &v);
+
+ DEFINE_FUNCTOR(pythonic::builtins, ord);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/print.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/print.hpp
new file mode 100644
index 00000000000..9e6599ffb90
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/print.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_PRINT_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_PRINT_HPP
+
+#include <ostream>
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ void print_nonl();
+
+ template <typename T, typename... Types>
+ void print_nonl(T const &value, Types const &... values);
+
+ void print();
+
+ template <typename T, typename... Types>
+ void print(T const &value, Types const &... values);
+ DEFINE_FUNCTOR(pythonic::builtins, print);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/StaticIfBreak.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/StaticIfBreak.hpp
new file mode 100644
index 00000000000..b631bfff7a8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/StaticIfBreak.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_PYTHRAN_STATICIFBREAK_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_PYTHRAN_STATICIFBREAK_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/static_if.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace pythran
+ {
+ template <class T>
+ types::StaticIfBreak<T> StaticIfBreak(T const &arg);
+
+ DEFINE_FUNCTOR(pythonic::builtins::pythran, StaticIfBreak);
+ }
+}
+
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/StaticIfCont.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/StaticIfCont.hpp
new file mode 100644
index 00000000000..4fc6f53af79
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/StaticIfCont.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_PYTHRAN_STATICIFCONT_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_PYTHRAN_STATICIFCONT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/static_if.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace pythran
+ {
+ template <class T>
+ types::StaticIfCont<T> StaticIfCont(T const &arg);
+
+ DEFINE_FUNCTOR(pythonic::builtins::pythran, StaticIfCont);
+ }
+}
+
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/StaticIfNoReturn.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/StaticIfNoReturn.hpp
new file mode 100644
index 00000000000..4f795c261bf
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/StaticIfNoReturn.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_PYTHRAN_STATICIFNORETURN_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_PYTHRAN_STATICIFNORETURN_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/static_if.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace pythran
+ {
+ template <class T>
+ types::StaticIfNoReturn<T> StaticIfNoReturn(T const &arg);
+
+ DEFINE_FUNCTOR(pythonic::builtins::pythran, StaticIfNoReturn);
+ }
+}
+
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/StaticIfReturn.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/StaticIfReturn.hpp
new file mode 100644
index 00000000000..766e5dc5ab5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/StaticIfReturn.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_PYTHRAN_STATICIFRETURN_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_PYTHRAN_STATICIFRETURN_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/static_if.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace pythran
+ {
+ template <class T>
+ types::StaticIfReturn<T> StaticIfReturn(T const &arg);
+
+ DEFINE_FUNCTOR(pythonic::builtins::pythran, StaticIfReturn);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/is_none.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/is_none.hpp
new file mode 100644
index 00000000000..d67e7fbda58
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/is_none.hpp
@@ -0,0 +1,132 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_PYTHRAN_IS_NONE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_PYTHRAN_IS_NONE_HPP
+
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace types
+{
+
+ struct false_type;
+
+ struct true_type {
+ operator bool() const
+ {
+ return true;
+ }
+ false_type operator!() const;
+ true_type operator&(true_type) const;
+ false_type operator&(false_type) const;
+ true_type operator|(true_type) const;
+ true_type operator|(false_type) const;
+ true_type operator==(true_type) const;
+ false_type operator==(false_type) const;
+ };
+
+ struct false_type {
+ operator bool() const
+ {
+ return false;
+ }
+ true_type operator!() const
+ {
+ return {};
+ }
+ false_type operator&(true_type)
+ {
+ return {};
+ }
+ false_type operator&(false_type)
+ {
+ return {};
+ }
+ true_type operator|(true_type)
+ {
+ return {};
+ }
+ false_type operator|(false_type)
+ {
+ return {};
+ }
+ false_type operator==(true_type)
+ {
+ return {};
+ }
+ true_type operator==(false_type)
+ {
+ return {};
+ }
+ };
+
+ inline false_type true_type::operator!() const
+ {
+ return {};
+ }
+ inline true_type true_type::operator&(true_type) const
+ {
+ return {};
+ }
+ inline false_type true_type::operator&(false_type) const
+ {
+ return {};
+ }
+ inline true_type true_type::operator|(true_type) const
+ {
+ return {};
+ }
+ inline true_type true_type::operator|(false_type) const
+ {
+ return {};
+ }
+ inline true_type true_type::operator==(true_type) const
+ {
+ return {};
+ }
+ inline false_type true_type::operator==(false_type) const
+ {
+ return {};
+ }
+} // namespace types
+
+namespace builtins
+{
+
+ namespace pythran
+ {
+ template <class T>
+ types::false_type is_none(T const &)
+ {
+ return {};
+ };
+
+ template <class T>
+ bool is_none(types::none<T> const &n)
+ {
+ return n.is_none;
+ };
+
+ inline types::true_type is_none(types::none_type const &)
+ {
+ return {};
+ };
+
+ DEFINE_FUNCTOR(pythonic::builtins::pythran, is_none);
+ } // namespace pythran
+} // namespace builtins
+
+#ifdef ENABLE_PYTHON_MODULE
+
+template <>
+struct to_python<types::true_type> : to_python<bool> {
+};
+template <>
+struct to_python<types::false_type> : to_python<bool> {
+};
+
+#endif
+
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/len_set.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/len_set.hpp
new file mode 100644
index 00000000000..474f991b17b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/len_set.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_PYTHRAN_LEN_SET_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_PYTHRAN_LEN_SET_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace pythran
+ {
+
+ template <class Iterable>
+ long len_set(Iterable const &s);
+
+ DEFINE_FUNCTOR(pythonic::builtins::pythran, len_set);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/or_.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/or_.hpp
new file mode 100644
index 00000000000..e84af2fe82d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/or_.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_PYTHRAN_OR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_PYTHRAN_OR_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/combined.hpp"
+#include "pythonic/include/types/lazy.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace pythran
+ {
+
+ template <class T0, class T1>
+ types::lazy_combined_t<T0, T1> or_(T0 &&, T1 &&);
+
+ DEFINE_FUNCTOR(pythonic::builtins::pythran, or_);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/static_if.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/static_if.hpp
new file mode 100644
index 00000000000..a678609de5d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/static_if.hpp
@@ -0,0 +1,91 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_PYTHRAN_STATIC_IF_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_PYTHRAN_STATIC_IF_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/builtins/pythran/is_none.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace pythran
+ {
+ namespace details
+ {
+ template <class IsSame>
+ struct static_if;
+
+ template <>
+ struct static_if<types::true_type> {
+ static_if(types::true_type)
+ {
+ }
+ template <class F0, class F1>
+ F0 operator()(F0 f0, F1 f1)
+ {
+ return f0;
+ }
+ };
+ template <>
+ struct static_if<types::false_type> {
+ static_if(types::false_type)
+ {
+ }
+ template <class F0, class F1>
+ F1 operator()(F0 f0, F1 f1)
+ {
+ return f1;
+ }
+ };
+ template <>
+ struct static_if<bool> {
+ bool state_;
+ static_if(bool state) : state_(state)
+ {
+ }
+
+ template <class F0, class F1>
+ struct merged {
+ bool state_;
+ F0 f0;
+ F1 f1;
+ merged(bool state, F0 f0, F1 f1) : state_(state), f0(f0), f1(f1)
+ {
+ }
+ template <class... Args>
+ auto operator()(Args &&... args) const -> typename __combined<
+ decltype(f0(std::forward<Args>(args)...)),
+ decltype(f1(std::forward<Args>(args)...))>::type
+ {
+ if (state_)
+ return f0(std::forward<Args>(args)...);
+ else
+ return f1(std::forward<Args>(args)...);
+ }
+ };
+
+ template <class F0, class F1>
+ merged<F0, F1> operator()(F0 f0, F1 f1)
+ {
+ return {state_, f0, f1};
+ }
+ };
+ }
+ template <class T, class F0, class F1>
+ auto static_if(T const &cond, F0 f0, F1 f1)
+ -> decltype(details::static_if<T>{cond}(f0, f1));
+
+ template <class F0, class F1>
+ auto static_if(int const &cond, F0 f0, F1 f1)
+ -> decltype(details::static_if<bool>{(bool)cond}(f0, f1))
+ {
+ return details::static_if<bool>{(bool)cond}(f0, f1);
+ }
+
+ DEFINE_FUNCTOR(pythonic::builtins::pythran, static_if);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/static_list.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/static_list.hpp
new file mode 100644
index 00000000000..3d6ba21c710
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/pythran/static_list.hpp
@@ -0,0 +1,44 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_PYTHRAN_STATIC_LIST_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_PYTHRAN_STATIC_LIST_HPP
+
+#include "pythonic/include/builtins/list.hpp"
+#include "pythonic/include/types/tuple.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace pythran
+ {
+ inline types::empty_list static_list(std::tuple<> const &other)
+ {
+ return {};
+ }
+ template <class T, size_t N>
+ types::static_list<T, N> static_list(types::array<T, N> const &other);
+ template <class T, size_t N>
+ types::static_list<T, N> static_list(types::array<T, N> &other);
+ template <class T, size_t N>
+ types::static_list<T, N> static_list(types::array<T, N> &&other);
+
+ template <class T>
+ auto static_list(T &&other) -> decltype(
+ pythonic::builtins::functor::list{}(std::forward<T>(other)));
+
+ template <class T0, class... Tys>
+ types::static_list<typename __combined<T0, Tys...>::type,
+ 1 + sizeof...(Tys)>
+ static_list(std::tuple<T0, Tys...> const &other)
+ {
+ return static_list(
+ types::to_array<typename __combined<T0, Tys...>::type>(other));
+ }
+
+ DEFINE_FUNCTOR(pythonic::builtins::pythran, static_list);
+ } // namespace pythran
+} // namespace builtins
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/reduce.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/reduce.hpp
new file mode 100644
index 00000000000..2084ccbf3ad
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/reduce.hpp
@@ -0,0 +1,42 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_REDUCE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_REDUCE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+#include <numeric>
+#include <utility>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ template <class Iterable, class Operator>
+ auto reduce(Operator op, Iterable s)
+ -> decltype(op(std::declval<typename std::iterator_traits<
+ typename Iterable::iterator>::value_type>(),
+ std::declval<typename std::iterator_traits<
+ typename Iterable::iterator>::value_type>()));
+
+ // this convoluted expression computes the fixed-point type of the output
+ // it's required because, e.g. static_list<long, 1> + static_list<long, 1>
+ // returns array<long, 2>
+ // and this widens to list
+ template <class Iterable, class Operator, class T>
+ using reduce_helper_t = typename __combined<
+ T, decltype(std::declval<Operator>()(
+ std::declval<T const &>(),
+ std::declval<typename std::iterator_traits<
+ typename Iterable::iterator>::value_type>()))>::type;
+
+ template <class Iterable, class Operator, class T>
+ auto reduce(Operator op, Iterable s, T const &init)
+ -> decltype(std::accumulate(
+ s.begin(), s.end(),
+ static_cast<reduce_helper_t<Iterable, Operator, T>>(init), op));
+
+ DEFINE_FUNCTOR(pythonic::builtins, reduce);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/reversed.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/reversed.hpp
new file mode 100644
index 00000000000..ead92971547
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/reversed.hpp
@@ -0,0 +1,38 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_REVERSED_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_REVERSED_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace details
+ {
+ template <class Iterable>
+ struct reversed {
+
+ using value_type = typename Iterable::value_type;
+ using iterator = typename Iterable::reverse_iterator;
+ using const_iterator = typename Iterable::const_reverse_iterator;
+
+ Iterable iterable;
+
+ reversed();
+ reversed(Iterable const &iterable);
+ iterator begin();
+ iterator end();
+ const_iterator begin() const;
+ const_iterator end() const;
+ };
+ }
+
+ template <class Iterable>
+ details::reversed<Iterable> reversed(Iterable const &iterable);
+
+ DEFINE_FUNCTOR(pythonic::builtins, reversed);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/round.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/round.hpp
new file mode 100644
index 00000000000..49563a81db4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/round.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_ROUND_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_ROUND_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+ template <class T>
+ double round(T const &v, size_t n);
+
+ template <class T>
+ double round(T const &v);
+
+ DEFINE_FUNCTOR(pythonic::builtins, round);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/set.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/set.hpp
new file mode 100644
index 00000000000..d5cf0c3dd36
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/set.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SET_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SET_HPP
+
+#include "pythonic/include/types/set.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace anonymous
+ {
+ inline types::empty_set set();
+
+ template <class Iterable>
+ inline types::set<typename std::iterator_traits<
+ typename std::remove_reference<Iterable>::type::iterator>::value_type>
+ set(Iterable &&t);
+ }
+
+ DEFINE_FUNCTOR(pythonic::builtins::anonymous, set);
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/set/add.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/set/add.hpp
new file mode 100644
index 00000000000..18794b4ba4a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/set/add.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SET_ADD_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SET_ADD_HPP
+
+#include "pythonic/include/types/set.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+
+ template <class T, class F>
+ types::none_type add(types::set<T> &s, F const &value);
+
+ template <class T, class F>
+ types::none_type add(types::set<T> &&s, F const &value);
+
+ template <class F>
+ types::none_type add(types::empty_set const &s, F &&value);
+
+ DEFINE_FUNCTOR(pythonic::builtins::set, add);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/set/clear.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/set/clear.hpp
new file mode 100644
index 00000000000..4ccfbe12bdd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/set/clear.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SET_CLEAR_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SET_CLEAR_HPP
+
+#include "pythonic/include/__dispatch__/clear.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace builtins
+{
+ namespace set
+ {
+ USING_FUNCTOR(clear, pythonic::__dispatch__::functor::clear);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/set/copy.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/set/copy.hpp
new file mode 100644
index 00000000000..f6628cd93f5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/set/copy.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SET_COPY_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SET_COPY_HPP
+
+#include "pythonic/include/__dispatch__/copy.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace builtins
+{
+ namespace set
+ {
+ USING_FUNCTOR(copy, pythonic::__dispatch__::functor::copy);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/set/difference.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/set/difference.hpp
new file mode 100644
index 00000000000..e246a88eb3a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/set/difference.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SET_DIFFERENCE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SET_DIFFERENCE_HPP
+
+#include "pythonic/include/types/set.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+
+ template <typename T, typename... Types>
+ types::set<T> difference(types::set<T> const &set, Types const &... others);
+
+ template <typename T, typename... Types>
+ types::set<T> difference(types::set<T> &&set, Types const &... others);
+
+ template <typename... Types>
+ types::empty_set difference(types::empty_set const &set,
+ Types const &... others);
+
+ template <typename T>
+ types::set<T> difference(types::set<T> const &set);
+
+ template <typename T>
+ types::set<T> difference(types::set<T> &&set);
+
+ types::empty_set difference(types::empty_set const &set);
+
+ DEFINE_FUNCTOR(pythonic::builtins::set, difference);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/set/difference_update.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/set/difference_update.hpp
new file mode 100644
index 00000000000..7057bb5cf58
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/set/difference_update.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SET_DIFFERENCEUPDATE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SET_DIFFERENCEUPDATE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/set.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+
+ template <typename T, typename... Types>
+ types::none_type difference_update(types::set<T> &set,
+ Types const &... others);
+
+ template <typename T, typename... Types>
+ types::none_type difference_update(types::set<T> &&set,
+ Types const &... others);
+
+ template <typename... Types>
+ types::none_type difference_update(types::empty_set const &set,
+ Types const &... others);
+
+ DEFINE_FUNCTOR(pythonic::builtins::set, difference_update);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/set/discard.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/set/discard.hpp
new file mode 100644
index 00000000000..1e79a834507
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/set/discard.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SET_DISCARD_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SET_DISCARD_HPP
+
+#include "pythonic/include/types/set.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+ template <class T, class U>
+ void discard(types::set<T> &set, U const &elem);
+
+ template <class T, class U>
+ void discard(types::set<T> &&set, U const &elem);
+
+ template <class U>
+ void discard(types::empty_set const &set, U const &elem);
+
+ DEFINE_FUNCTOR(pythonic::builtins::set, discard);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/set/intersection.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/set/intersection.hpp
new file mode 100644
index 00000000000..eb4e34d1722
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/set/intersection.hpp
@@ -0,0 +1,33 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SET_INTERSECTION_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SET_INTERSECTION_HPP
+
+#include "pythonic/include/types/set.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+
+ template <typename T, typename... Types>
+ typename __combined<types::set<T>, Types...>::type
+ intersection(types::set<T> const &set, Types const &... others);
+
+ /* No rvalue overload possible because of return type modification.:
+ * >>> a = set([1,2,3])
+ * >>> b = set([1., 2., 3.])
+ * >>> a.intersection(b)
+ * set([1.0, 2.0, 3.0])
+ */
+ template <typename... Types>
+ types::empty_set intersection(types::empty_set const &set,
+ Types const &... others);
+
+ DEFINE_FUNCTOR(pythonic::builtins::set, intersection);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/set/intersection_update.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/set/intersection_update.hpp
new file mode 100644
index 00000000000..e7d4583cf42
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/set/intersection_update.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SET_INTERSECTIONUPDATE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SET_INTERSECTIONUPDATE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/set.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+
+ template <typename T, typename... Types>
+ types::none_type intersection_update(types::set<T> &set,
+ Types const &... others);
+
+ template <typename T, typename... Types>
+ types::none_type intersection_update(types::set<T> &&set,
+ Types const &... others);
+
+ template <typename... Types>
+ types::none_type intersection_update(types::empty_set &&set,
+ Types const &... others);
+
+ DEFINE_FUNCTOR(pythonic::builtins::set, intersection_update);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/set/isdisjoint.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/set/isdisjoint.hpp
new file mode 100644
index 00000000000..0edf1bd0017
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/set/isdisjoint.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SET_ISDISJOINT_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SET_ISDISJOINT_HPP
+
+#include "pythonic/include/types/set.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+ template <class T, class U>
+ bool isdisjoint(types::set<T> const &calling_set, U const &arg_set);
+
+ template <class U>
+ bool isdisjoint(types::empty_set const &calling_set, U const &arg_set);
+
+ DEFINE_FUNCTOR(pythonic::builtins::set, isdisjoint);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/set/issubset.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/set/issubset.hpp
new file mode 100644
index 00000000000..8748d64acde
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/set/issubset.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SET_ISSUBSET_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SET_ISSUBSET_HPP
+
+#include "pythonic/include/types/set.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+
+ template <class T, class U>
+ bool issubset(types::set<T> const &set, U const &other);
+
+ template <class U>
+ bool issubset(types::empty_set const &set, U const &other);
+
+ DEFINE_FUNCTOR(pythonic::builtins::set, issubset);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/set/issuperset.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/set/issuperset.hpp
new file mode 100644
index 00000000000..3b32830f28e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/set/issuperset.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SET_ISSUPERSET_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SET_ISSUPERSET_HPP
+
+#include "pythonic/include/types/set.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+
+ template <class T, class U>
+ bool issuperset(types::set<T> const &set, U const &other);
+
+ template <class U>
+ bool issuperset(types::empty_set const &set, U const &other);
+
+ DEFINE_FUNCTOR(pythonic::builtins::set, issuperset);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/set/remove.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/set/remove.hpp
new file mode 100644
index 00000000000..cd1edc50e7a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/set/remove.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SET_REMOVE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SET_REMOVE_HPP
+
+#include "pythonic/include/__dispatch__/remove.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace builtins
+{
+ namespace set
+ {
+ USING_FUNCTOR(remove, pythonic::__dispatch__::functor::remove);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/set/symmetric_difference.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/set/symmetric_difference.hpp
new file mode 100644
index 00000000000..916449ae261
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/set/symmetric_difference.hpp
@@ -0,0 +1,35 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SET_SYMMETRICDIFFERENCE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SET_SYMMETRICDIFFERENCE_HPP
+
+#include "pythonic/include/types/set.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+
+ template <typename T, typename U>
+ typename __combined<types::set<T>, U>::type
+ symmetric_difference(types::set<T> const &set, U const &other);
+
+ /* No rvalue overload possible because of return type modification.:
+ * >>> a = set([1, 2, 3])
+ * >>> b = set([2., 3., 4.])
+ * >>> a.symmetric_difference(b)
+ * set([1.0, 4.0])
+ */
+
+ // combiner is used as other may be list but return is a set
+ template <typename U>
+ typename __combined<types::empty_set, U>::type
+ symmetric_difference(types::empty_set const &set, U const &other);
+
+ DEFINE_FUNCTOR(pythonic::builtins::set, symmetric_difference);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/set/symmetric_difference_update.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/set/symmetric_difference_update.hpp
new file mode 100644
index 00000000000..094bc118435
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/set/symmetric_difference_update.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SET_SYMMETRICDIFFERENCEUPDATE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SET_SYMMETRICDIFFERENCEUPDATE_HPP
+
+#include "pythonic/include/types/set.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+
+ template <typename T, typename U>
+ types::none_type symmetric_difference_update(types::set<T> &set,
+ U const &other);
+
+ template <typename T, typename U>
+ types::none_type symmetric_difference_update(types::set<T> &&set,
+ U const &other);
+
+ template <typename U>
+ types::none_type symmetric_difference_update(types::empty_set const &set,
+ U const &other);
+
+ DEFINE_FUNCTOR(pythonic::builtins::set, symmetric_difference_update);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/set/union_.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/set/union_.hpp
new file mode 100644
index 00000000000..92f0741359c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/set/union_.hpp
@@ -0,0 +1,35 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SET_UNION_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SET_UNION_HPP
+
+#include "pythonic/include/types/set.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace set
+ {
+
+ template <typename T, typename... Types>
+ typename __combined<types::set<T>, Types...>::type
+ union_(types::set<T> const &set, Types const &... others);
+
+ template <typename... Types>
+ typename __combined<types::empty_set, Types...>::type
+ union_(types::empty_set const &init, Types const &... others);
+
+ template <typename T>
+ types::set<T> union_(types::set<T> const &set);
+
+ template <typename T>
+ typename __combined<types::empty_set, T>::type union_(T const &set);
+
+ types::empty_set union_(types::empty_set const &init);
+
+ DEFINE_FUNCTOR(pythonic::builtins::set, union_);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/set/update.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/set/update.hpp
new file mode 100644
index 00000000000..99163e3ecbb
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/set/update.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SET_UPDATE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SET_UPDATE_HPP
+
+#include "pythonic/include/__dispatch__/update.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace builtins
+{
+ namespace set
+ {
+ USING_FUNCTOR(update, pythonic::__dispatch__::functor::update);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/slice.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/slice.hpp
new file mode 100644
index 00000000000..e8437d11a5f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/slice.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SLICE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SLICE_HPP
+
+#include "pythonic/include/types/slice.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace anonymous
+ {
+ types::cstride_slice<1> slice(types::none<long> stop);
+ types::cstride_slice<1> slice(types::none<long> start,
+ types::none<long> stop);
+ types::slice slice(types::none<long> start, types::none<long> stop,
+ types::none<long> step);
+ } // namespace anonymous
+
+ DEFINE_FUNCTOR(pythonic::builtins::anonymous, slice);
+} // namespace builtins
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/sorted.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/sorted.hpp
new file mode 100644
index 00000000000..be2859f02f2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/sorted.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SORTED_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SORTED_HPP
+
+#include "pythonic/include/types/list.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ template <class Iterable>
+ types::list<typename std::remove_cv<typename std::iterator_traits<
+ typename std::decay<Iterable>::type::iterator>::value_type>::type>
+ sorted(Iterable &&seq);
+
+ template <class Iterable, class Key>
+ types::list<typename std::remove_cv<typename std::iterator_traits<
+ typename std::decay<Iterable>::type::iterator>::value_type>::type>
+ sorted(Iterable &&seq, Key const &key, bool reverse = false);
+
+ template <class Iterable>
+ types::list<typename std::remove_cv<typename std::iterator_traits<
+ typename std::decay<Iterable>::type::iterator>::value_type>::type>
+ sorted(Iterable &&seq, types::none_type const &key, bool reverse = false);
+
+ DEFINE_FUNCTOR(pythonic::builtins, sorted);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/str/__mod__.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/str/__mod__.hpp
new file mode 100644
index 00000000000..e598da55b52
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/str/__mod__.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_STR_MOD_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_STR_MOD_HPP
+
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+ template <class T>
+ types::str __mod__(types::str const &, T const &arg);
+ template <class... Ts>
+ types::str __mod__(types::str const &, std::tuple<Ts...> const &args);
+ template <size_t N, class T>
+ types::str __mod__(types::str const &, types::array<T, N> const &args);
+
+ DEFINE_FUNCTOR(pythonic::builtins::str, __mod__);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/str/capitalize.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/str/capitalize.hpp
new file mode 100644
index 00000000000..fdf49293134
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/str/capitalize.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_STR_CAPITALIZE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_STR_CAPITALIZE_HPP
+
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ types::str capitalize(types::str const &s);
+
+ DEFINE_FUNCTOR(pythonic::builtins::str, capitalize);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/str/count.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/str/count.hpp
new file mode 100644
index 00000000000..35c0a6ae884
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/str/count.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_STR_COUNT_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_STR_COUNT_HPP
+
+#include "pythonic/include/__dispatch__/count.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace builtins
+{
+ namespace str
+ {
+ USING_FUNCTOR(count, pythonic::__dispatch__::functor::count);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/str/endswith.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/str/endswith.hpp
new file mode 100644
index 00000000000..78f94b170c5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/str/endswith.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_STR_ENDSWITH_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_STR_ENDSWITH_HPP
+
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ // TODO : Add implementation for tuple as first argument.
+ bool endswith(types::str const &s, types::str const &suffix, long start = 0,
+ long end = -1);
+
+ DEFINE_FUNCTOR(pythonic::builtins::str, endswith);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/str/find.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/str/find.hpp
new file mode 100644
index 00000000000..b9852d98cb8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/str/find.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_STR_FIND_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_STR_FIND_HPP
+
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ long find(types::str const &s, types::str const &value, long start,
+ long end);
+
+ long find(types::str const &s, types::str const &value, long start);
+
+ long find(types::str const &s, types::str const &value);
+
+ DEFINE_FUNCTOR(pythonic::builtins::str, find);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/str/isalpha.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/str/isalpha.hpp
new file mode 100644
index 00000000000..463f4f25a2f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/str/isalpha.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_STR_ISALPHA_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_STR_ISALPHA_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/str.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ bool isalpha(types::str const &s);
+
+ DEFINE_FUNCTOR(pythonic::builtins::str, isalpha);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/str/isdigit.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/str/isdigit.hpp
new file mode 100644
index 00000000000..5771c7da4c3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/str/isdigit.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_STR_ISDIGIT_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_STR_ISDIGIT_HPP
+
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ bool isdigit(types::str const &s);
+
+ DEFINE_FUNCTOR(pythonic::builtins::str, isdigit);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/str/join.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/str/join.hpp
new file mode 100644
index 00000000000..aa566d1e4d4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/str/join.hpp
@@ -0,0 +1,46 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_STR_JOIN_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_STR_JOIN_HPP
+
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ /* Join for string.join(string) */
+ template <class S>
+ types::str join(S const &s, types::str const &iterable);
+
+ /* Join for string.join(random acces iter but ! on string) */
+ template <class S, class Iterable>
+ typename std::enable_if<
+ !std::is_same<typename std::remove_cv<
+ typename std::remove_reference<Iterable>::type>::type,
+ types::str>::value &&
+ std::is_same<
+ typename std::iterator_traits<typename std::remove_reference<
+ Iterable>::type::iterator>::iterator_category,
+ std::random_access_iterator_tag>::value,
+ types::str>::type
+ join(S const &s, Iterable &&iterable);
+
+ /* Join for string.join(forward iterator) */
+ template <class S, class Iterable>
+ typename std::enable_if<
+ !std::is_same<
+ typename std::iterator_traits<typename std::remove_reference<
+ Iterable>::type::iterator>::iterator_category,
+ std::random_access_iterator_tag>::value,
+ types::str>::type
+ join(S const &s, Iterable &&iterable);
+
+ DEFINE_FUNCTOR(pythonic::builtins::str, join);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/str/lower.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/str/lower.hpp
new file mode 100644
index 00000000000..b204a5c25ba
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/str/lower.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_STR_LOWER_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_STR_LOWER_HPP
+
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ types::str lower(types::str const &s);
+
+ DEFINE_FUNCTOR(pythonic::builtins::str, lower);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/str/lstrip.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/str/lstrip.hpp
new file mode 100644
index 00000000000..23c75f03716
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/str/lstrip.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_STR_LSTRIP_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_STR_LSTRIP_HPP
+
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+ types::str lstrip(types::str const &self, types::str const &to_del = " ");
+
+ DEFINE_FUNCTOR(pythonic::builtins::str, lstrip);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/str/replace.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/str/replace.hpp
new file mode 100644
index 00000000000..2493f641457
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/str/replace.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_STR_REPLACE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_STR_REPLACE_HPP
+
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ types::str replace(types::str const &self, types::str const &old_pattern,
+ types::str const &new_pattern,
+ long count = std::numeric_limits<long>::max());
+
+ DEFINE_FUNCTOR(pythonic::builtins::str, replace);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/str/rstrip.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/str/rstrip.hpp
new file mode 100644
index 00000000000..db2d6a27173
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/str/rstrip.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_STR_RSTRIP_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_STR_RSTRIP_HPP
+
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ types::str rstrip(types::str const &self, types::str const &to_del = " ");
+
+ DEFINE_FUNCTOR(pythonic::builtins::str, rstrip);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/str/split.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/str/split.hpp
new file mode 100644
index 00000000000..a2d19f60f0e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/str/split.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_STR_SPLIT_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_STR_SPLIT_HPP
+
+#include "pythonic/include/types/list.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ types::list<types::str> split(types::str const &in, types::str const &sep,
+ long maxsplit = -1);
+
+ types::list<types::str> split(types::str const &s,
+ types::none_type const & = {},
+ long maxsplit = -1);
+
+ DEFINE_FUNCTOR(pythonic::builtins::str, split);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/str/startswith.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/str/startswith.hpp
new file mode 100644
index 00000000000..e1931d2e78a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/str/startswith.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_STR_STARTSWITH_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_STR_STARTSWITH_HPP
+
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ bool startswith(types::str const &s, types::str const &prefix,
+ long start = 0, long end = -1);
+
+ DEFINE_FUNCTOR(pythonic::builtins::str, startswith);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/str/strip.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/str/strip.hpp
new file mode 100644
index 00000000000..ec045f11181
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/str/strip.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_STR_STRIP_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_STR_STRIP_HPP
+
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ types::str strip(types::str const &self, types::str const &to_del = " \n");
+
+ DEFINE_FUNCTOR(pythonic::builtins::str, strip);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/str/upper.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/str/upper.hpp
new file mode 100644
index 00000000000..6c1b0279f1e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/str/upper.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_STR_UPPER_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_STR_UPPER_HPP
+
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace str
+ {
+
+ types::str upper(types::str const &s);
+
+ DEFINE_FUNCTOR(pythonic::builtins::str, upper);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/sum.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/sum.hpp
new file mode 100644
index 00000000000..d33137066a7
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/sum.hpp
@@ -0,0 +1,59 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_SUM_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_SUM_HPP
+
+#include "pythonic/include/types/assignable.hpp"
+#include "pythonic/include/types/tuple.hpp"
+#include "pythonic/include/utils/int_.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+#include <numeric>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace details
+ {
+ template <class Tuple, size_t N>
+ struct tuple_sum {
+ auto operator()(Tuple const &t)
+ -> decltype(std::get<N>(t) + tuple_sum<Tuple, N - 1>()(t));
+ };
+
+ template <class Tuple>
+ struct tuple_sum<Tuple, 0> {
+ auto operator()(Tuple const &t) -> decltype(std::get<0>(t));
+ };
+ }
+
+ template <class Iterable, class T>
+ auto sum(Iterable s, T start) -> decltype(std::accumulate(
+ s.begin(), s.end(),
+ static_cast<typename assignable<decltype(start + *s.begin())>::type>(
+ start)));
+
+ template <class Iterable>
+ auto sum(Iterable s) -> decltype(sum(s, 0L))
+ {
+ return sum(s, 0L);
+ }
+
+ template <class... Types>
+ auto sum(std::tuple<Types...> const &t) -> decltype(
+ details::tuple_sum<std::tuple<Types...>, sizeof...(Types)-1>()(t))
+ {
+ return details::tuple_sum<std::tuple<Types...>, sizeof...(Types)-1>()(t);
+ }
+
+ template <class T, size_t N, class V>
+ T sum(types::array_base<T, N, V> const &t)
+ {
+ return details::tuple_sum<types::array_base<T, N, V>, N - 1>()(t);
+ }
+
+ DEFINE_FUNCTOR(pythonic::builtins, sum);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/type.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/type.hpp
new file mode 100644
index 00000000000..d115066a797
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/type.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_TYPE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_TYPE_HPP
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+ template <class T>
+ struct type_functor;
+
+ template <class T>
+ typename type_functor<T>::type type(T const &t);
+ DEFINE_FUNCTOR(pythonic::builtins, type);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/xrange.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/xrange.hpp
new file mode 100644
index 00000000000..340eeabd141
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/xrange.hpp
@@ -0,0 +1,57 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_XRANGE_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_XRANGE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <iterator>
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ namespace
+ {
+ struct xrange_iterator
+ : std::iterator<std::random_access_iterator_tag, long, ptrdiff_t,
+ long *, long /*no ref here*/> {
+ long value_;
+ long step_;
+
+ xrange_iterator() = default;
+ xrange_iterator(long v, long s);
+ long operator*() const;
+ xrange_iterator &operator++();
+ xrange_iterator operator++(int);
+ xrange_iterator &operator+=(long n);
+ bool operator!=(xrange_iterator const &other) const;
+ bool operator==(xrange_iterator const &other) const;
+ bool operator<(xrange_iterator const &other) const;
+ long operator-(xrange_iterator const &other) const;
+ };
+ }
+
+ struct xrange {
+ using value_type = long;
+ using iterator = xrange_iterator;
+ using const_iterator = xrange_iterator;
+ using reverse_iterator = xrange_iterator;
+ using const_reverse_iterator = xrange_iterator;
+
+ long begin_;
+ long end_;
+ long step_;
+
+ xrange() = default;
+ xrange(long b, long e, long s = 1);
+ xrange(long e);
+ iterator begin() const;
+ iterator end() const;
+ reverse_iterator rbegin() const;
+ reverse_iterator rend() const;
+ };
+
+ DEFINE_FUNCTOR(pythonic::builtins, xrange);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/builtins/zip.hpp b/contrib/python/pythran/pythran/pythonic/include/builtins/zip.hpp
new file mode 100644
index 00000000000..d37be63b66f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/builtins/zip.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_BUILTIN_ZIP_HPP
+#define PYTHONIC_INCLUDE_BUILTIN_ZIP_HPP
+
+#include "pythonic/include/builtins/None.hpp"
+#include "pythonic/include/builtins/map.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+
+ template <typename... Iter>
+ auto zip(Iter &&... iters)
+ -> decltype(map(builtins::None, std::forward<Iter>(iters)...));
+
+ DEFINE_FUNCTOR(pythonic::builtins, zip);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/cmath/acos.hpp b/contrib/python/pythran/pythran/pythonic/include/cmath/acos.hpp
new file mode 100644
index 00000000000..71ac51e739f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/cmath/acos.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_CMATH_ACOS_HPP
+#define PYTHONIC_INCLUDE_CMATH_ACOS_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+ DEFINE_FUNCTOR_2(acos, std::acos);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/cmath/acosh.hpp b/contrib/python/pythran/pythran/pythonic/include/cmath/acosh.hpp
new file mode 100644
index 00000000000..46d979f9166
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/cmath/acosh.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_CMATH_ACOSH_HPP
+#define PYTHONIC_INCLUDE_CMATH_ACOSH_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+ DEFINE_FUNCTOR_2(acosh, std::acosh);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/cmath/asin.hpp b/contrib/python/pythran/pythran/pythonic/include/cmath/asin.hpp
new file mode 100644
index 00000000000..f5e8fb2e1dd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/cmath/asin.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_CMATH_ASIN_HPP
+#define PYTHONIC_INCLUDE_CMATH_ASIN_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+ DEFINE_FUNCTOR_2(asin, std::asin);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/cmath/asinh.hpp b/contrib/python/pythran/pythran/pythonic/include/cmath/asinh.hpp
new file mode 100644
index 00000000000..ba7fa7ee2e5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/cmath/asinh.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_CMATH_ASINH_HPP
+#define PYTHONIC_INCLUDE_CMATH_ASINH_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+ DEFINE_FUNCTOR_2(asinh, std::asinh);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/cmath/atan.hpp b/contrib/python/pythran/pythran/pythonic/include/cmath/atan.hpp
new file mode 100644
index 00000000000..9cef6406d77
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/cmath/atan.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_CMATH_ATAN_HPP
+#define PYTHONIC_INCLUDE_CMATH_ATAN_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+ DEFINE_FUNCTOR_2(atan, std::atan);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/cmath/atanh.hpp b/contrib/python/pythran/pythran/pythonic/include/cmath/atanh.hpp
new file mode 100644
index 00000000000..ede7ff35f9a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/cmath/atanh.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_CMATH_ATANH_HPP
+#define PYTHONIC_INCLUDE_CMATH_ATANH_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+ DEFINE_FUNCTOR_2(atanh, std::atanh);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/cmath/cos.hpp b/contrib/python/pythran/pythran/pythonic/include/cmath/cos.hpp
new file mode 100644
index 00000000000..f5071fc02be
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/cmath/cos.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_INCLUDE_CMATH_COS_HPP
+#define PYTHONIC_INCLUDE_CMATH_COS_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+ template <class T>
+ std::complex<T> cos(std::complex<T> const &v);
+ template <class T>
+ std::complex<T> cos(T const &v);
+
+ DEFINE_FUNCTOR(pythonic::cmath, cos);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/cmath/cosh.hpp b/contrib/python/pythran/pythran/pythonic/include/cmath/cosh.hpp
new file mode 100644
index 00000000000..905b213209c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/cmath/cosh.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_CMATH_COSH_HPP
+#define PYTHONIC_INCLUDE_CMATH_COSH_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+ DEFINE_FUNCTOR_2(cosh, std::cosh);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/cmath/e.hpp b/contrib/python/pythran/pythran/pythonic/include/cmath/e.hpp
new file mode 100644
index 00000000000..d128c68dbea
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/cmath/e.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_CMATH_E_HPP
+#define PYTHONIC_INCLUDE_CMATH_E_HPP
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/include/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+ double constexpr e = std::exp(1);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/cmath/exp.hpp b/contrib/python/pythran/pythran/pythonic/include/cmath/exp.hpp
new file mode 100644
index 00000000000..8c5b3ba1f1d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/cmath/exp.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_CMATH_EXP_HPP
+#define PYTHONIC_INCLUDE_CMATH_EXP_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+ DEFINE_FUNCTOR_2(exp, std::exp);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/cmath/isinf.hpp b/contrib/python/pythran/pythran/pythonic/include/cmath/isinf.hpp
new file mode 100644
index 00000000000..1b1a0e13dea
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/cmath/isinf.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_CMATH_ISINF_HPP
+#define PYTHONIC_INCLUDE_CMATH_ISINF_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+ DEFINE_FUNCTOR_2(isinf, std::isinf);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/cmath/isnan.hpp b/contrib/python/pythran/pythran/pythonic/include/cmath/isnan.hpp
new file mode 100644
index 00000000000..be7cc9ad842
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/cmath/isnan.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_CMATH_ISNAN_HPP
+#define PYTHONIC_INCLUDE_CMATH_ISNAN_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+ DEFINE_FUNCTOR_2(isnan, std::isnan);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/cmath/log.hpp b/contrib/python/pythran/pythran/pythonic/include/cmath/log.hpp
new file mode 100644
index 00000000000..dd59e40200f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/cmath/log.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_CMATH_LOG_HPP
+#define PYTHONIC_INCLUDE_CMATH_LOG_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+ using std::log;
+ double log(double x, double base);
+ DEFINE_FUNCTOR(pythonic::cmath, log);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/cmath/log10.hpp b/contrib/python/pythran/pythran/pythonic/include/cmath/log10.hpp
new file mode 100644
index 00000000000..85851944a52
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/cmath/log10.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_CMATH_LOG10_HPP
+#define PYTHONIC_INCLUDE_CMATH_LOG10_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+ DEFINE_FUNCTOR_2(log10, std::log10);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/cmath/pi.hpp b/contrib/python/pythran/pythran/pythonic/include/cmath/pi.hpp
new file mode 100644
index 00000000000..6ddfe9f8d1f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/cmath/pi.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_CMATH_PI_HPP
+#define PYTHONIC_INCLUDE_CMATH_PI_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+ double constexpr pi = std::atan(1) * 4;
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/cmath/sin.hpp b/contrib/python/pythran/pythran/pythonic/include/cmath/sin.hpp
new file mode 100644
index 00000000000..699b9268c6e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/cmath/sin.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_CMATH_SIN_HPP
+#define PYTHONIC_INCLUDE_CMATH_SIN_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+ DEFINE_FUNCTOR_2(sin, std::sin);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/cmath/sinh.hpp b/contrib/python/pythran/pythran/pythonic/include/cmath/sinh.hpp
new file mode 100644
index 00000000000..42a64fba04f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/cmath/sinh.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_CMATH_SINH_HPP
+#define PYTHONIC_INCLUDE_CMATH_SINH_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+ DEFINE_FUNCTOR_2(sinh, std::sinh);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/cmath/sqrt.hpp b/contrib/python/pythran/pythran/pythonic/include/cmath/sqrt.hpp
new file mode 100644
index 00000000000..4a78f2d1d85
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/cmath/sqrt.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_CMATH_SQRT_HPP
+#define PYTHONIC_INCLUDE_CMATH_SQRT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+ DEFINE_FUNCTOR_2(sqrt, std::sqrt);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/cmath/tan.hpp b/contrib/python/pythran/pythran/pythonic/include/cmath/tan.hpp
new file mode 100644
index 00000000000..605d6a56725
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/cmath/tan.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_CMATH_TAN_HPP
+#define PYTHONIC_INCLUDE_CMATH_TAN_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+ DEFINE_FUNCTOR_2(tan, std::tan);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/cmath/tanh.hpp b/contrib/python/pythran/pythran/pythonic/include/cmath/tanh.hpp
new file mode 100644
index 00000000000..8a628bd5cc4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/cmath/tanh.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_CMATH_TANH_HPP
+#define PYTHONIC_INCLUDE_CMATH_TANH_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/complex.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace cmath
+{
+ DEFINE_FUNCTOR_2(tanh, std::tanh);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/functools/partial.hpp b/contrib/python/pythran/pythran/pythonic/include/functools/partial.hpp
new file mode 100644
index 00000000000..ab6698502da
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/functools/partial.hpp
@@ -0,0 +1,64 @@
+#ifndef PYTHONIC_INCLUDE_FUNCTOOLS_PARTIAL_HPP
+#define PYTHONIC_INCLUDE_FUNCTOOLS_PARTIAL_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/seq.hpp"
+
+#include <utility>
+#include <tuple>
+
+PYTHONIC_NS_BEGIN
+
+namespace functools
+{
+
+ namespace details
+ {
+
+ /* a task that captures its environment for later call */
+ template <typename... ClosureTypes>
+ struct task {
+
+ using callable = void;
+ friend std::ostream &operator<<(std::ostream &os, task)
+ {
+ return os << "partial_function_wrapper";
+ }
+
+ mutable std::tuple<ClosureTypes...> closure; // closure associated to
+ // the task, mutable
+ // because pythran assumes
+ // all function calls are
+ // const
+
+ task();
+ task(task const &) = default;
+ task(ClosureTypes const &... types);
+
+ template <std::size_t... S, typename... Types>
+ auto call(utils::index_sequence<S...>, Types &&... types) const
+ -> decltype(std::get<0>(closure)(std::get<S + 1>(closure)...,
+ std::forward<Types>(types)...))
+ {
+ return std::get<0>(closure)(std::get<S + 1>(closure)...,
+ std::forward<Types>(types)...);
+ }
+
+ template <typename... Types>
+ auto operator()(Types &&... types) const -> decltype(
+ this->call(utils::make_index_sequence<sizeof...(ClosureTypes)-1>(),
+ std::forward<Types>(types)...));
+ };
+ }
+
+ template <typename... Types>
+ // remove references as closure capture the env by copy
+ details::task<typename std::remove_cv<
+ typename std::remove_reference<Types>::type>::type...>
+ partial(Types &&... types);
+
+ DEFINE_FUNCTOR(pythonic::functools, partial);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/functools/reduce.hpp b/contrib/python/pythran/pythran/pythonic/include/functools/reduce.hpp
new file mode 100644
index 00000000000..02bb5bac486
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/functools/reduce.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_FUNCTOOLS_REDUCE_HPP
+#define PYTHONIC_INCLUDE_FUNCTOOLS_REDUCE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/builtins/reduce.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace functools
+{
+ USING_FUNCTOR(reduce, builtins::functor::reduce);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/close.hpp b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/close.hpp
new file mode 100644
index 00000000000..ae538dda8bf
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/close.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_CLOSE_HPP
+#define PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_CLOSE_HPP
+
+#include "pythonic/include/builtins/file/close.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace io
+{
+
+ namespace _io
+ {
+ namespace TextIOWrapper
+ {
+ USING_FUNCTOR(close, builtins::file::functor::close);
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/fileno.hpp b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/fileno.hpp
new file mode 100644
index 00000000000..3798ee16d1a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/fileno.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_FILENO_HPP
+#define PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_FILENO_HPP
+
+#include "pythonic/include/builtins/file/fileno.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace io
+{
+
+ namespace _io
+ {
+ namespace TextIOWrapper
+ {
+ USING_FUNCTOR(fileno, builtins::file::functor::fileno);
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/flush.hpp b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/flush.hpp
new file mode 100644
index 00000000000..48b802af02d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/flush.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_FLUSH_HPP
+#define PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_FLUSH_HPP
+
+#include "pythonic/include/builtins/file/flush.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace io
+{
+
+ namespace _io
+ {
+ namespace TextIOWrapper
+ {
+ USING_FUNCTOR(flush, builtins::file::functor::flush);
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/isatty.hpp b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/isatty.hpp
new file mode 100644
index 00000000000..f489ce43561
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/isatty.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_ISATTY_HPP
+#define PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_ISATTY_HPP
+
+#include "pythonic/include/builtins/file/isatty.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace io
+{
+
+ namespace _io
+ {
+ namespace TextIOWrapper
+ {
+ USING_FUNCTOR(isatty, builtins::file::functor::isatty);
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/next.hpp b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/next.hpp
new file mode 100644
index 00000000000..6b81cfbd988
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/next.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_NEXT_HPP
+#define PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_NEXT_HPP
+
+#include "pythonic/include/builtins/file/next.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace io
+{
+
+ namespace _io
+ {
+ namespace TextIOWrapper
+ {
+ USING_FUNCTOR(next, builtins::file::functor::next);
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/read.hpp b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/read.hpp
new file mode 100644
index 00000000000..8a168d3276f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/read.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_READ_HPP
+#define PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_READ_HPP
+
+#include "pythonic/include/builtins/file/read.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace io
+{
+
+ namespace _io
+ {
+ namespace TextIOWrapper
+ {
+ USING_FUNCTOR(read, builtins::file::functor::read);
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/readline.hpp b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/readline.hpp
new file mode 100644
index 00000000000..8a81030be1a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/readline.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_READLINE_HPP
+#define PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_READLINE_HPP
+
+#include "pythonic/include/builtins/file/readline.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace io
+{
+
+ namespace _io
+ {
+ namespace TextIOWrapper
+ {
+ USING_FUNCTOR(readline, builtins::file::functor::readline);
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/readlines.hpp b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/readlines.hpp
new file mode 100644
index 00000000000..d4df432dfa6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/readlines.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_READLINES_HPP
+#define PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_READLINES_HPP
+
+#include "pythonic/include/builtins/file/readlines.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace io
+{
+
+ namespace _io
+ {
+ namespace TextIOWrapper
+ {
+ USING_FUNCTOR(readlines, builtins::file::functor::readlines);
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/seek.hpp b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/seek.hpp
new file mode 100644
index 00000000000..0bd1b54c7a6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/seek.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_SEEK_HPP
+#define PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_SEEK_HPP
+
+#include "pythonic/include/builtins/file/seek.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace io
+{
+
+ namespace _io
+ {
+ namespace TextIOWrapper
+ {
+ USING_FUNCTOR(seek, builtins::file::functor::seek);
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/tell.hpp b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/tell.hpp
new file mode 100644
index 00000000000..09deee54ae8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/tell.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_TELL_HPP
+#define PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_TELL_HPP
+
+#include "pythonic/include/builtins/file/tell.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace io
+{
+
+ namespace _io
+ {
+ namespace TextIOWrapper
+ {
+ USING_FUNCTOR(tell, builtins::file::functor::tell);
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/truncate.hpp b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/truncate.hpp
new file mode 100644
index 00000000000..9dd855b7458
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/truncate.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_TRUNCATE_HPP
+#define PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_TRUNCATE_HPP
+
+#include "pythonic/include/builtins/file/truncate.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace io
+{
+
+ namespace _io
+ {
+ namespace TextIOWrapper
+ {
+ USING_FUNCTOR(truncate, builtins::file::functor::truncate);
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/write.hpp b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/write.hpp
new file mode 100644
index 00000000000..90813ffebc4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/write.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_WRITE_HPP
+#define PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_WRITE_HPP
+
+#include "pythonic/include/builtins/file/write.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace io
+{
+
+ namespace _io
+ {
+ namespace TextIOWrapper
+ {
+ USING_FUNCTOR(write, builtins::file::functor::write);
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/writelines.hpp b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/writelines.hpp
new file mode 100644
index 00000000000..ff55e19760e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/io/_io/TextIOWrapper/writelines.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_WRITELINES_HPP
+#define PYTHONIC_INCLUDE_IO__IO_TEXTIOWRAPPER_WRITELINES_HPP
+
+#include "pythonic/include/builtins/file/writelines.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace io
+{
+
+ namespace _io
+ {
+ namespace TextIOWrapper
+ {
+ USING_FUNCTOR(writelines, builtins::file::functor::writelines);
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/itertools/combinations.hpp b/contrib/python/pythran/pythran/pythonic/include/itertools/combinations.hpp
new file mode 100644
index 00000000000..9b7894033b8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/itertools/combinations.hpp
@@ -0,0 +1,85 @@
+#ifndef PYTHONIC_INCLUDE_ITERTOOLS_COMBINATIONS_HPP
+#define PYTHONIC_INCLUDE_ITERTOOLS_COMBINATIONS_HPP
+
+#include "pythonic/include/types/dynamic_tuple.hpp"
+#include "pythonic/include/utils/allocate.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+#include <iterator>
+#include <vector>
+
+PYTHONIC_NS_BEGIN
+
+namespace itertools
+{
+ namespace details
+ {
+ template <class T>
+ struct combination_iterator
+ : std::iterator<std::forward_iterator_tag,
+ types::dynamic_tuple<typename T::value_type>, ptrdiff_t,
+ types::dynamic_tuple<typename T::value_type> *,
+ types::dynamic_tuple<typename T::value_type> /*no ref*/
+ > {
+ std::vector<typename T::value_type,
+ utils::allocator<typename T::value_type>>
+ pool;
+ std::vector<long, utils::allocator<long>> indices;
+ long r;
+ bool stopped;
+ std::vector<typename T::value_type,
+ utils::allocator<typename T::value_type>>
+ result;
+
+ combination_iterator() = default;
+ combination_iterator(bool);
+
+ template <class Iter>
+ combination_iterator(Iter &&pool, long r);
+
+ types::dynamic_tuple<typename T::value_type> operator*() const;
+ combination_iterator &operator++();
+ bool operator!=(combination_iterator const &other) const;
+ bool operator==(combination_iterator const &other) const;
+ bool operator<(combination_iterator const &other) const;
+ };
+
+ template <class T>
+ struct combination : combination_iterator<T> {
+ using iterator = combination_iterator<T>;
+ using value_type = typename iterator::value_type;
+
+ long num_elts;
+
+ combination() = default;
+
+ template <class Iter>
+ combination(Iter &&iter, long elts);
+ iterator const &begin() const;
+ iterator begin();
+ iterator end() const;
+ };
+ } // namespace details
+
+ template <typename T0>
+ details::combination<
+ typename std::remove_cv<typename std::remove_reference<T0>::type>::type>
+ combinations(T0 &&iter, long num_elts);
+
+ DEFINE_FUNCTOR(pythonic::itertools, combinations);
+} // namespace itertools
+PYTHONIC_NS_END
+
+/* type inference stuff {*/
+#include "pythonic/include/types/combined.hpp"
+
+template <class E, class T>
+struct __combined<E, pythonic::itertools::details::combination<T>> {
+ using type =
+ typename __combined<E, container<typename pythonic::itertools::details::
+ combination<T>::value_type>>::type;
+};
+
+/* } */
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/itertools/common.hpp b/contrib/python/pythran/pythran/pythonic/include/itertools/common.hpp
new file mode 100644
index 00000000000..41295a771dd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/itertools/common.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_ITERTOOLS_COMMON_HPP
+#define PYTHONIC_INCLUDE_ITERTOOLS_COMMON_HPP
+
+PYTHONIC_NS_BEGIN
+
+namespace itertools
+{
+
+ struct npos {
+ };
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/itertools/count.hpp b/contrib/python/pythran/pythran/pythonic/include/itertools/count.hpp
new file mode 100644
index 00000000000..16956112d8b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/itertools/count.hpp
@@ -0,0 +1,65 @@
+#ifndef PYTHONIC_INCLUDE_ITERTOOLS_COUNT_HPP
+#define PYTHONIC_INCLUDE_ITERTOOLS_COUNT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/combined.hpp"
+
+#include <iterator>
+
+PYTHONIC_NS_BEGIN
+
+namespace itertools
+{
+ namespace details
+ {
+ template <class T>
+ struct count_iterator : std::iterator<std::random_access_iterator_tag, T> {
+ T value;
+ T step;
+ count_iterator() = default;
+ count_iterator(T value, T step);
+ T operator*() const;
+ count_iterator &operator++();
+ count_iterator &operator+=(long n);
+ bool operator!=(count_iterator const &other) const;
+ bool operator==(count_iterator const &other) const;
+ bool operator<(count_iterator const &other) const;
+ long operator-(count_iterator const &other) const;
+ };
+
+ template <class T>
+ struct count : count_iterator<T> {
+ using value_type = T;
+ using iterator = count_iterator<T>;
+
+ count() = default;
+ count(T value, T step);
+ iterator &begin();
+ iterator const &begin() const;
+ iterator end() const;
+ };
+ }
+
+ template <typename T0, typename T1 = T0>
+ details::count<typename __combined<T0, T1>::type> count(T0 start,
+ T1 step = 1);
+
+ details::count<long> count();
+
+ DEFINE_FUNCTOR(pythonic::itertools, count);
+}
+PYTHONIC_NS_END
+
+/* type inference stuff {*/
+#include "pythonic/include/types/combined.hpp"
+
+template <class E, class T>
+struct __combined<E, pythonic::itertools::details::count<T>> {
+ using type =
+ typename __combined<E, container<typename pythonic::itertools::details::
+ count<T>::value_type>>::type;
+};
+
+/* } */
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/itertools/ifilter.hpp b/contrib/python/pythran/pythran/pythonic/include/itertools/ifilter.hpp
new file mode 100644
index 00000000000..bc5c33dcf4e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/itertools/ifilter.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_ITERTOOLS_IFILTER_HPP
+#define PYTHONIC_INCLUDE_ITERTOOLS_IFILTER_HPP
+
+#include "pythonic/include/builtins/filter.hpp"
+#include "pythonic/include/itertools/common.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/iterator.hpp"
+
+#include <iterator>
+#include <type_traits>
+
+PYTHONIC_NS_BEGIN
+
+namespace itertools
+{
+
+ template <typename Operator, typename List0>
+ details::filter<typename std::remove_cv<
+ typename std::remove_reference<Operator>::type>::type,
+ typename std::remove_cv<
+ typename std::remove_reference<List0>::type>::type>
+ ifilter(Operator &&_op, List0 &&_seq);
+
+ DEFINE_FUNCTOR(pythonic::itertools, ifilter);
+} // namespace itertools
+
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/itertools/islice.hpp b/contrib/python/pythran/pythran/pythonic/include/itertools/islice.hpp
new file mode 100644
index 00000000000..69c0afdad9f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/itertools/islice.hpp
@@ -0,0 +1,81 @@
+#ifndef PYTHONIC_INCLUDE_ITERTOOLS_ISLICE_HPP
+#define PYTHONIC_INCLUDE_ITERTOOLS_ISLICE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/itertools/common.hpp"
+#include "pythonic/include/builtins/range.hpp"
+#include <iterator>
+
+PYTHONIC_NS_BEGIN
+
+namespace itertools
+{
+ template <typename Iterable>
+ struct islice_iterator
+ : std::iterator<typename Iterable::iterator::iterator_category,
+ typename std::iterator_traits<
+ typename Iterable::iterator>::value_type> {
+ typename std::remove_reference<
+ typename std::remove_cv<Iterable>::type>::type iterable_ref;
+ typename std::remove_reference<
+ typename std::remove_cv<Iterable>::type>::type::iterator iterable;
+
+ builtins::range xr_ref;
+ builtins::range_iterator state;
+ builtins::range_iterator::value_type prev;
+
+ islice_iterator();
+ islice_iterator(Iterable const &iterable, builtins::range const &xr);
+ islice_iterator(npos const &n, Iterable const &iterable,
+ builtins::range const &xr);
+
+ typename Iterable::value_type operator*() const;
+ islice_iterator &operator++();
+ bool operator==(islice_iterator const &other) const;
+ bool operator!=(islice_iterator const &other) const;
+ bool operator<(islice_iterator const &other) const;
+ int operator-(islice_iterator const &other) const;
+ };
+
+ template <typename Iterable>
+ struct _islice : islice_iterator<Iterable> {
+
+ using iterator = islice_iterator<Iterable>;
+ using value_type = typename Iterable::value_type;
+
+ iterator end_iter;
+
+ _islice();
+ _islice(Iterable const &iterable, builtins::range const &xr);
+
+ iterator &begin();
+ iterator const &begin() const;
+ iterator end() const;
+ };
+
+ template <typename Iterable>
+ _islice<typename std::remove_cv<
+ typename std::remove_reference<Iterable>::type>::type>
+ islice(Iterable &&iterable, long start, long stop, long step = 1);
+
+ template <typename Iterable>
+ _islice<typename std::remove_cv<
+ typename std::remove_reference<Iterable>::type>::type>
+ islice(Iterable &&iterable, long stop);
+
+ DEFINE_FUNCTOR(pythonic::itertools, islice);
+}
+PYTHONIC_NS_END
+
+/* type inference stuff {*/
+#include "pythonic/include/types/combined.hpp"
+
+template <class E, class T>
+struct __combined<E, pythonic::itertools::_islice<T>> {
+ using type = typename __combined<
+ E, container<typename pythonic::itertools::_islice<T>::value_type>>::type;
+};
+
+/* } */
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/itertools/permutations.hpp b/contrib/python/pythran/pythran/pythonic/include/itertools/permutations.hpp
new file mode 100644
index 00000000000..5aff43d0411
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/itertools/permutations.hpp
@@ -0,0 +1,111 @@
+#ifndef PYTHONIC_INCLUDE_ITERTOOLS_PERMUTATIONS_HPP
+#define PYTHONIC_INCLUDE_ITERTOOLS_PERMUTATIONS_HPP
+
+#include "pythonic/include/types/dynamic_tuple.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+#include "pythonic/utils/allocate.hpp"
+
+#include <iterator>
+#include <vector>
+
+PYTHONIC_NS_BEGIN
+
+namespace itertools
+{
+ /** Permutation iterator
+ *
+ * It wraps a vector && provide an iteration over every possible
+ * permutation of the vector. The permutations are represented as
+ *dynamic_tuple
+ * of elements.
+ *
+ * The following iterator:
+ *
+ * permutations_iterator([0, 1, 2])
+ *
+ * yields the following suite:
+ *
+ * [(0, 1, 2), (0, 2, 1), (1, 0, 2), (1, 2, 0), (2, 0, 1), (2, 1, 0)]
+ *
+ */
+ template <class T, class H>
+ struct permutations_iterator : std::iterator<std::forward_iterator_tag, H,
+ ptrdiff_t, H *, H /* no ref*/
+ > {
+
+ // Vector of inputs, contains elements to permute
+ using pool_type = std::vector<typename T::value_type,
+ utils::allocator<typename T::value_type>>;
+ pool_type pool;
+
+ // The current permutation as a dynamic_tuple of index in the pool
+ // Internally it always has the same size as the pool, even if the
+ // external view is limited
+ std::vector<long, utils::allocator<long>> curr_permut;
+
+ // Size of the "visible" permutation
+ size_t _size;
+ bool end; // sentinel marker
+
+ permutations_iterator();
+ permutations_iterator(pool_type const &iter, size_t num_elts, bool end);
+
+ /** Build the permutation visible from the "outside" */
+ H operator*() const;
+
+ /* Generate next permutation
+ *
+ * If the size of the permutation is smaller than the size of the
+ * pool, we may have to iterate multiple times
+ */
+ permutations_iterator &operator++();
+ bool operator!=(permutations_iterator const &other) const;
+ bool operator==(permutations_iterator const &other) const;
+ bool operator<(permutations_iterator const &other) const;
+ };
+
+ template <class T, class H>
+ // FIXME document why this inheritance???
+ struct _permutations : permutations_iterator<T, H> {
+ using iterator = permutations_iterator<T, H>;
+ using value_type = typename iterator::value_type;
+
+ _permutations();
+ _permutations(T iter, long elts);
+
+ iterator const &begin() const;
+ iterator begin();
+ iterator end() const;
+ };
+
+ template <typename T0>
+ _permutations<T0, types::dynamic_tuple<typename T0::value_type>>
+ permutations(T0 iter, long num_elts);
+
+ template <typename T0>
+ _permutations<T0, types::dynamic_tuple<typename T0::value_type>>
+ permutations(T0 iter);
+
+ template <typename T0, long N0>
+ _permutations<T0, types::array<typename T0::value_type, (size_t)N0>>
+ permutations(T0 iter, std::integral_constant<long, N0>);
+
+ DEFINE_FUNCTOR(pythonic::itertools, permutations);
+} // namespace itertools
+PYTHONIC_NS_END
+
+/* type inference stuff {*/
+#include "pythonic/include/types/combined.hpp"
+
+template <class E, class T, class H>
+struct __combined<E, pythonic::itertools::_permutations<T, H>> {
+ using type =
+ typename __combined<E,
+ container<typename pythonic::itertools::_permutations<
+ T, H>::value_type>>::type;
+};
+
+/* } */
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/itertools/product.hpp b/contrib/python/pythran/pythran/pythonic/include/itertools/product.hpp
new file mode 100644
index 00000000000..7ca6f0c6a99
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/itertools/product.hpp
@@ -0,0 +1,92 @@
+#ifndef PYTHONIC_INCLUDE_ITERTOOLS_PRODUCT_HPP
+#define PYTHONIC_INCLUDE_ITERTOOLS_PRODUCT_HPP
+
+#include "pythonic/include/utils/iterator.hpp"
+#include "pythonic/include/utils/seq.hpp"
+#include "pythonic/include/utils/int_.hpp"
+#include "pythonic/include/itertools/common.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+#include <iterator>
+#include <type_traits>
+
+PYTHONIC_NS_BEGIN
+
+namespace itertools
+{
+ namespace details
+ {
+
+ // FIXME : should be a combined_iterator_tag
+ template <typename... Iters>
+ struct product_iterator
+ : std::iterator<std::forward_iterator_tag,
+ types::make_tuple_t<typename Iters::value_type...>> {
+
+ std::tuple<typename Iters::iterator...> const it_begin;
+ std::tuple<typename Iters::iterator...> const it_end;
+ std::tuple<typename Iters::iterator...> it;
+ bool end;
+
+ product_iterator() = default;
+ template <size_t... I>
+ product_iterator(std::tuple<Iters...> &_iters,
+ utils::index_sequence<I...> const &);
+ template <size_t... I>
+ product_iterator(npos, std::tuple<Iters...> &_iters,
+ utils::index_sequence<I...> const &);
+ types::make_tuple_t<typename Iters::value_type...> operator*() const;
+ product_iterator &operator++();
+ bool operator==(product_iterator const &other) const;
+ bool operator!=(product_iterator const &other) const;
+ bool operator<(product_iterator const &other) const;
+
+ private:
+ template <size_t N>
+ void advance(utils::int_<N>);
+ void advance(utils::int_<0>);
+ template <size_t... I>
+ types::make_tuple_t<typename Iters::value_type...>
+ get_value(utils::index_sequence<I...> const &) const;
+ };
+
+ template <typename... Iters>
+ struct product : utils::iterator_reminder<true, Iters...>,
+ product_iterator<Iters...> {
+
+ using value_type = types::make_tuple_t<typename Iters::value_type...>;
+ using iterator = product_iterator<Iters...>;
+
+ iterator end_iter;
+
+ product() = default;
+ product(Iters const &... _iters);
+
+ iterator &begin();
+ iterator const &begin() const;
+ iterator const &end() const;
+ };
+ }
+
+ template <typename... Iter>
+ details::product<typename std::remove_cv<
+ typename std::remove_reference<Iter>::type>::type...>
+ product(Iter &&... iters);
+
+ DEFINE_FUNCTOR(pythonic::itertools, product);
+}
+PYTHONIC_NS_END
+
+/* type inference stuff {*/
+#include "pythonic/include/types/combined.hpp"
+
+template <class E, class... Iter>
+struct __combined<E, pythonic::itertools::details::product<Iter...>> {
+ using type =
+ typename __combined<E, container<typename pythonic::itertools::details::
+ product<Iter...>::value_type>>::type;
+};
+
+/* } */
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/itertools/repeat.hpp b/contrib/python/pythran/pythran/pythonic/include/itertools/repeat.hpp
new file mode 100644
index 00000000000..c827e8d5e38
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/itertools/repeat.hpp
@@ -0,0 +1,61 @@
+#ifndef PYTHONIC_INCLUDE_ITERTOOLS_REPEAT_HPP
+#define PYTHONIC_INCLUDE_ITERTOOLS_REPEAT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+#include <iterator>
+
+PYTHONIC_NS_BEGIN
+
+namespace itertools
+{
+ template <class T, bool Endless>
+ struct repeat_iterator : std::iterator<std::forward_iterator_tag, T,
+ ptrdiff_t, T *, T /* no ref*/
+ > {
+ T value_;
+ long count_;
+
+ repeat_iterator(T value, long count);
+ repeat_iterator &operator++();
+ T operator*();
+ bool operator!=(repeat_iterator const &other) const;
+ bool operator==(repeat_iterator const &other) const;
+ bool operator<(repeat_iterator const &other) const;
+ };
+
+ template <class T, bool Endless>
+ struct _repeat : repeat_iterator<T, Endless> {
+ using iterator = repeat_iterator<T, Endless>;
+ using value_type = typename iterator::value_type;
+
+ _repeat() = default;
+ _repeat(T value, long count);
+
+ iterator begin() const;
+ iterator end() const;
+ };
+
+ template <typename T>
+ _repeat<T, false> repeat(T value, long num_elts);
+
+ template <typename T>
+ _repeat<T, true> repeat(T iter);
+
+ DEFINE_FUNCTOR(pythonic::itertools, repeat);
+}
+PYTHONIC_NS_END
+
+/* type inference stuff {*/
+#include "pythonic/include/types/combined.hpp"
+
+template <class E, class T, bool C>
+struct __combined<E, pythonic::itertools::_repeat<T, C>> {
+ using type = typename __combined<
+ E,
+ container<typename pythonic::itertools::_repeat<T, C>::value_type>>::type;
+};
+
+/* } */
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/acos.hpp b/contrib/python/pythran/pythran/pythonic/include/math/acos.hpp
new file mode 100644
index 00000000000..296f91d83f8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/acos.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_ACOS_HPP
+#define PYTHONIC_INCLUDE_MATH_ACOS_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(acos, std::acos);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/acosh.hpp b/contrib/python/pythran/pythran/pythonic/include/math/acosh.hpp
new file mode 100644
index 00000000000..9f52b8d56ff
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/acosh.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_ACOSH_HPP
+#define PYTHONIC_INCLUDE_MATH_ACOSH_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(acosh, std::acosh);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/asin.hpp b/contrib/python/pythran/pythran/pythonic/include/math/asin.hpp
new file mode 100644
index 00000000000..4f0da5947bc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/asin.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_ASIN_HPP
+#define PYTHONIC_INCLUDE_MATH_ASIN_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(asin, std::asin);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/asinh.hpp b/contrib/python/pythran/pythran/pythonic/include/math/asinh.hpp
new file mode 100644
index 00000000000..f68092db665
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/asinh.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_ASINH_HPP
+#define PYTHONIC_INCLUDE_MATH_ASINH_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(asinh, std::asinh);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/atan.hpp b/contrib/python/pythran/pythran/pythonic/include/math/atan.hpp
new file mode 100644
index 00000000000..d0fdf12164d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/atan.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_ATAN_HPP
+#define PYTHONIC_INCLUDE_MATH_ATAN_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(atan, std::atan);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/atan2.hpp b/contrib/python/pythran/pythran/pythonic/include/math/atan2.hpp
new file mode 100644
index 00000000000..bec3abcfa4a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/atan2.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_ATAN2_HPP
+#define PYTHONIC_INCLUDE_MATH_ATAN2_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(atan2, std::atan2);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/atanh.hpp b/contrib/python/pythran/pythran/pythonic/include/math/atanh.hpp
new file mode 100644
index 00000000000..55e8a166316
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/atanh.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_ATANH_HPP
+#define PYTHONIC_INCLUDE_MATH_ATANH_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(atanh, std::atanh);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/ceil.hpp b/contrib/python/pythran/pythran/pythonic/include/math/ceil.hpp
new file mode 100644
index 00000000000..2b496014623
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/ceil.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_MATH_CEIL_HPP
+#define PYTHONIC_INCLUDE_MATH_CEIL_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ template <class T>
+ long ceil(T x);
+
+ DEFINE_FUNCTOR(pythonic::math, ceil);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/copysign.hpp b/contrib/python/pythran/pythran/pythonic/include/math/copysign.hpp
new file mode 100644
index 00000000000..253473ced9a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/copysign.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_COPYSIGN_HPP
+#define PYTHONIC_INCLUDE_MATH_COPYSIGN_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(copysign, std::copysign);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/cos.hpp b/contrib/python/pythran/pythran/pythonic/include/math/cos.hpp
new file mode 100644
index 00000000000..d4296f65fe6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/cos.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_COS_HPP
+#define PYTHONIC_INCLUDE_MATH_COS_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(cos, std::cos);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/cosh.hpp b/contrib/python/pythran/pythran/pythonic/include/math/cosh.hpp
new file mode 100644
index 00000000000..860b8d79363
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/cosh.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_COSH_HPP
+#define PYTHONIC_INCLUDE_MATH_COSH_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(cosh, std::cosh);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/degrees.hpp b/contrib/python/pythran/pythran/pythonic/include/math/degrees.hpp
new file mode 100644
index 00000000000..724ffd310e2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/degrees.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_MATH_DEGREES_HPP
+#define PYTHONIC_INCLUDE_MATH_DEGREES_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+
+ template <class T>
+ double degrees(T x);
+
+ DEFINE_FUNCTOR(pythonic::math, degrees);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/e.hpp b/contrib/python/pythran/pythran/pythonic/include/math/e.hpp
new file mode 100644
index 00000000000..c23c704e57f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/e.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_E_HPP
+#define PYTHONIC_INCLUDE_MATH_E_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ double constexpr e = M_E;
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/erf.hpp b/contrib/python/pythran/pythran/pythonic/include/math/erf.hpp
new file mode 100644
index 00000000000..2a8105e4b2c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/erf.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_ERF_HPP
+#define PYTHONIC_INCLUDE_MATH_ERF_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(erf, std::erf);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/erfc.hpp b/contrib/python/pythran/pythran/pythonic/include/math/erfc.hpp
new file mode 100644
index 00000000000..3416fa9248e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/erfc.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_ERFC_HPP
+#define PYTHONIC_INCLUDE_MATH_ERFC_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(erfc, std::erfc);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/exp.hpp b/contrib/python/pythran/pythran/pythonic/include/math/exp.hpp
new file mode 100644
index 00000000000..a28c0966b7a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/exp.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_EXP_HPP
+#define PYTHONIC_INCLUDE_MATH_EXP_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(exp, std::exp);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/expm1.hpp b/contrib/python/pythran/pythran/pythonic/include/math/expm1.hpp
new file mode 100644
index 00000000000..32316e43e1b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/expm1.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_EXPM1_HPP
+#define PYTHONIC_INCLUDE_MATH_EXPM1_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(expm1, std::expm1);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/fabs.hpp b/contrib/python/pythran/pythran/pythonic/include/math/fabs.hpp
new file mode 100644
index 00000000000..6c762212e12
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/fabs.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_FABS_HPP
+#define PYTHONIC_INCLUDE_MATH_FABS_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(fabs, std::fabs);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/factorial.hpp b/contrib/python/pythran/pythran/pythonic/include/math/factorial.hpp
new file mode 100644
index 00000000000..cbfc0612821
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/factorial.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_MATH_FACTORIAL_HPP
+#define PYTHONIC_INCLUDE_MATH_FACTORIAL_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+
+ template <class T>
+ T factorial(T x);
+
+ DEFINE_FUNCTOR(pythonic::math, factorial);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/floor.hpp b/contrib/python/pythran/pythran/pythonic/include/math/floor.hpp
new file mode 100644
index 00000000000..8e2b82dd29b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/floor.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_MATH_FLOOR_HPP
+#define PYTHONIC_INCLUDE_MATH_FLOOR_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ template <class T>
+ long floor(T x);
+
+ DEFINE_FUNCTOR(pythonic::math, floor);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/fmod.hpp b/contrib/python/pythran/pythran/pythonic/include/math/fmod.hpp
new file mode 100644
index 00000000000..6000a858e6a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/fmod.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_FMOD_HPP
+#define PYTHONIC_INCLUDE_MATH_FMOD_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(fmod, std::fmod);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/frexp.hpp b/contrib/python/pythran/pythran/pythonic/include/math/frexp.hpp
new file mode 100644
index 00000000000..56d6a80427d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/frexp.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_MATH_FREXP_HPP
+#define PYTHONIC_INCLUDE_MATH_FREXP_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/tuple.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ std::tuple<double, long> frexp(double x);
+ DEFINE_FUNCTOR(pythonic::math, frexp);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/gamma.hpp b/contrib/python/pythran/pythran/pythonic/include/math/gamma.hpp
new file mode 100644
index 00000000000..19e7d1eb8c7
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/gamma.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_INCLUDE_MATH_GAMMA_HPP
+#define PYTHONIC_INCLUDE_MATH_GAMMA_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ double gamma(double x);
+ DEFINE_FUNCTOR(pythonic::math, gamma);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/hypot.hpp b/contrib/python/pythran/pythran/pythonic/include/math/hypot.hpp
new file mode 100644
index 00000000000..376ebbfdedc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/hypot.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_MATH_HYPOT_HPP
+#define PYTHONIC_INCLUDE_MATH_HYPOT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+#undef hypot
+// This is a windows defined macro that clash with std::hypot && our hypot
+// function
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(hypot, std::hypot);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/isinf.hpp b/contrib/python/pythran/pythran/pythonic/include/math/isinf.hpp
new file mode 100644
index 00000000000..6c5f8b0d9e2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/isinf.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_MATH_ISINF_HPP
+#define PYTHONIC_INCLUDE_MATH_ISINF_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ template <class T>
+ bool isinf(T const &v)
+ {
+ return std::isinf(v);
+ }
+ DEFINE_FUNCTOR(pythonic::math, isinf);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/isnan.hpp b/contrib/python/pythran/pythran/pythonic/include/math/isnan.hpp
new file mode 100644
index 00000000000..8d48155d4b7
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/isnan.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_ISNAN_HPP
+#define PYTHONIC_INCLUDE_MATH_ISNAN_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(isnan, std::isnan);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/ldexp.hpp b/contrib/python/pythran/pythran/pythonic/include/math/ldexp.hpp
new file mode 100644
index 00000000000..6a2b4deee3a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/ldexp.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_LDEXP_HPP
+#define PYTHONIC_INCLUDE_MATH_LDEXP_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(ldexp, std::ldexp);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/lgamma.hpp b/contrib/python/pythran/pythran/pythonic/include/math/lgamma.hpp
new file mode 100644
index 00000000000..a5b79d240e9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/lgamma.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_LGAMMA_HPP
+#define PYTHONIC_INCLUDE_MATH_LGAMMA_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(lgamma, std::lgamma);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/log.hpp b/contrib/python/pythran/pythran/pythonic/include/math/log.hpp
new file mode 100644
index 00000000000..0d4090d3c9f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/log.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_MATH_LOG_HPP
+#define PYTHONIC_INCLUDE_MATH_LOG_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ using std::log;
+ double log(double x, double base);
+ DEFINE_FUNCTOR(pythonic::math, log);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/log10.hpp b/contrib/python/pythran/pythran/pythonic/include/math/log10.hpp
new file mode 100644
index 00000000000..4ccfa854221
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/log10.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_LOG10_HPP
+#define PYTHONIC_INCLUDE_MATH_LOG10_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(log10, std::log10);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/log1p.hpp b/contrib/python/pythran/pythran/pythonic/include/math/log1p.hpp
new file mode 100644
index 00000000000..49ce9cbfd31
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/log1p.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_LOG1P_HPP
+#define PYTHONIC_INCLUDE_MATH_LOG1P_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(log1p, std::log1p);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/modf.hpp b/contrib/python/pythran/pythran/pythonic/include/math/modf.hpp
new file mode 100644
index 00000000000..a3ccd0e8c67
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/modf.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_MATH_MODF_HPP
+#define PYTHONIC_INCLUDE_MATH_MODF_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/tuple.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ std::tuple<double, double> modf(double x);
+ DEFINE_FUNCTOR(pythonic::math, modf);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/pi.hpp b/contrib/python/pythran/pythran/pythonic/include/math/pi.hpp
new file mode 100644
index 00000000000..c7cc32985fd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/pi.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_MATH_PI_HPP
+#define PYTHONIC_INCLUDE_MATH_PI_HPP
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ // see https://meetingcpp.com/blog/items/cpp-and-pi.html
+ double constexpr pi =
+ 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651e+00;
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/pow.hpp b/contrib/python/pythran/pythran/pythonic/include/math/pow.hpp
new file mode 100644
index 00000000000..491c853080a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/pow.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_POW_HPP
+#define PYTHONIC_INCLUDE_MATH_POW_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(pow, std::pow);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/radians.hpp b/contrib/python/pythran/pythran/pythonic/include/math/radians.hpp
new file mode 100644
index 00000000000..1262a000f67
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/radians.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_MATH_RADIANS_HPP
+#define PYTHONIC_INCLUDE_MATH_RADIANS_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/math/pi.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ template <class T>
+ double radians(T x);
+ DEFINE_FUNCTOR(pythonic::math, radians);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/sin.hpp b/contrib/python/pythran/pythran/pythonic/include/math/sin.hpp
new file mode 100644
index 00000000000..ee77bb765ca
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/sin.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_SIN_HPP
+#define PYTHONIC_INCLUDE_MATH_SIN_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(sin, std::sin);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/sinh.hpp b/contrib/python/pythran/pythran/pythonic/include/math/sinh.hpp
new file mode 100644
index 00000000000..d5d2b290dbf
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/sinh.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_SINH_HPP
+#define PYTHONIC_INCLUDE_MATH_SINH_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(sinh, std::sinh);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/sqrt.hpp b/contrib/python/pythran/pythran/pythonic/include/math/sqrt.hpp
new file mode 100644
index 00000000000..a643c160f80
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/sqrt.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_SQRT_HPP
+#define PYTHONIC_INCLUDE_MATH_SQRT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(sqrt, std::sqrt);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/tan.hpp b/contrib/python/pythran/pythran/pythonic/include/math/tan.hpp
new file mode 100644
index 00000000000..3dec4ae63ff
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/tan.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_TAN_HPP
+#define PYTHONIC_INCLUDE_MATH_TAN_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(tan, std::tan);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/tanh.hpp b/contrib/python/pythran/pythran/pythonic/include/math/tanh.hpp
new file mode 100644
index 00000000000..e94eed78645
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/tanh.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_MATH_TANH_HPP
+#define PYTHONIC_INCLUDE_MATH_TANH_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ DEFINE_FUNCTOR_2(tanh, std::tanh);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/math/trunc.hpp b/contrib/python/pythran/pythran/pythonic/include/math/trunc.hpp
new file mode 100644
index 00000000000..bdb454b109b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/math/trunc.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_MATH_TRUNC_HPP
+#define PYTHONIC_INCLUDE_MATH_TRUNC_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ template <class T>
+ long trunc(T x);
+
+ DEFINE_FUNCTOR(pythonic::math, trunc);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/NINF.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/NINF.hpp
new file mode 100644
index 00000000000..7b1d1d844c0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/NINF.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NINF_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NINF_HPP
+
+#include <limits>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ double const NINF = -std::numeric_limits<double>::infinity();
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/absolute.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/absolute.hpp
new file mode 100644
index 00000000000..1b421ac57ab
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/absolute.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ABSOLUTE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ABSOLUTE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/numpy/abs.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ USING_FUNCTOR(absolute, numpy::functor::abs);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/add.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/add.hpp
new file mode 100644
index 00000000000..fbae482f7ad
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/add.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ADD_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ADD_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/operator_/add.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME add
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::add
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/add/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/add/accumulate.hpp
new file mode 100644
index 00000000000..fd1f55dd9bc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/add/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ADD_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ADD_ACCUMULATE_HPP
+
+#define UFUNC_NAME add
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/add/reduce.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/add/reduce.hpp
new file mode 100644
index 00000000000..5b39a4ecea4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/add/reduce.hpp
@@ -0,0 +1,10 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ADD_REDUCE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ADD_REDUCE_HPP
+
+#define UFUNC_NAME add
+#define UFUNC_INAME iadd
+#include "pythonic/include/numpy/ufunc_reduce.hpp"
+#undef UFUNC_NAME
+#undef UFUNC_INAME
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/alen.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/alen.hpp
new file mode 100644
index 00000000000..6deccde09a5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/alen.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ALEN_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ALEN_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T>
+ long alen(T &&expr);
+
+ DEFINE_FUNCTOR(pythonic::numpy, alen);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/all.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/all.hpp
new file mode 100644
index 00000000000..77cc158b55e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/all.hpp
@@ -0,0 +1,41 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ALL_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ALL_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/numpy/multiply.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ typename std::enable_if<types::is_numexpr_arg<E>::value, bool>::type
+ all(E const &expr, types::none_type _ = types::none_type());
+
+ template <class E>
+ typename std::enable_if<
+ std::is_scalar<E>::value || types::is_complex<E>::value, bool>::type
+ all(E const &expr, types::none_type _ = types::none_type());
+
+ template <class E>
+ auto all(E const &array, long axis) ->
+ typename std::enable_if<std::is_scalar<E>::value ||
+ types::is_complex<E>::value,
+ decltype(all(array))>::type;
+
+ template <class E>
+ auto all(E const &array, long axis) ->
+ typename std::enable_if<E::value == 1, decltype(all(array))>::type;
+
+ template <class E>
+ typename std::enable_if<
+ E::value != 1,
+ types::ndarray<typename E::dtype, types::array<long, E::value - 1>>>::type
+ all(E const &array, long axis);
+
+ DEFINE_FUNCTOR(pythonic::numpy, all);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/allclose.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/allclose.hpp
new file mode 100644
index 00000000000..07b26d49410
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/allclose.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ALLCLOSE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ALLCLOSE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/numpy/abs.hpp"
+#include "pythonic/include/numpy/isfinite.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class U, class V>
+ bool allclose(U const &u, V const &v, double rtol = 1e-5, double atol = 1e-8);
+
+ DEFINE_FUNCTOR(pythonic::numpy, allclose);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/alltrue.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/alltrue.hpp
new file mode 100644
index 00000000000..da988f7a42e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/alltrue.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ALLTRUE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ALLTRUE_HPP
+
+#include "pythonic/include/numpy/all.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class... Types>
+ auto alltrue(Types &&... types)
+ -> decltype(all(std::forward<Types>(types)...));
+
+ DEFINE_FUNCTOR(pythonic::numpy, alltrue);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/amax.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/amax.hpp
new file mode 100644
index 00000000000..c423be9fed4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/amax.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_AMAX_HPP
+#define PYTHONIC_INCLUDE_NUMPY_AMAX_HPP
+
+#include "pythonic/include/numpy/max.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ USING_FUNCTOR(amax, max);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/amin.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/amin.hpp
new file mode 100644
index 00000000000..84b086b4c20
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/amin.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_AMIN_HPP
+#define PYTHONIC_INCLUDE_NUMPY_AMIN_HPP
+
+#include "pythonic/include/numpy/min.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ USING_FUNCTOR(amin, min);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/angle.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/angle.hpp
new file mode 100644
index 00000000000..991ed7e3bf7
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/angle.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ANGLE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ANGLE_HPP
+
+#include "pythonic/include/numpy/angle_in_deg.hpp"
+#include "pythonic/include/numpy/angle_in_rad.hpp"
+#include "pythonic/include/types/assignable.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T>
+ auto angle(T const &t, bool in_deg) ->
+ typename assignable<decltype(functor::angle_in_rad()(t))>::type;
+
+ // Numpy_expr can be use if only the first argument is given.
+ template <class T>
+ auto angle(T const &t) -> decltype(functor::angle_in_rad()(t));
+
+ DEFINE_FUNCTOR(pythonic::numpy, angle);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/angle_in_deg.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/angle_in_deg.hpp
new file mode 100644
index 00000000000..210bc94cec8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/angle_in_deg.hpp
@@ -0,0 +1,32 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ANGLEINDEG_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ANGLEINDEG_HPP
+
+#include "pythonic/include/numpy/angle_in_rad.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include "pythonic/include/numpy/pi.hpp"
+
+/* NOTE: angle_in_deg is not part of the official Numpy API,
+ * this file is here only to split the angle function in two parts
+ */
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace wrapper
+ {
+ template <class T>
+ auto angle_in_deg(T const &t) -> decltype(angle_in_rad(t) * 180 / pi)
+ {
+ return angle_in_rad(t) * 180 / pi;
+ }
+ }
+#define NUMPY_NARY_FUNC_NAME angle_in_deg
+#define NUMPY_NARY_FUNC_SYM wrapper::angle_in_deg
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/angle_in_rad.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/angle_in_rad.hpp
new file mode 100644
index 00000000000..5f5d7def3bb
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/angle_in_rad.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ANGLEINRAD_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ANGLEINRAD_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/numpy/arctan.hpp"
+
+/* NOTE: angle_in_rad is not part of the official Numpy API,
+ * this file is here only to split the angle function in two parts
+ */
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T>
+ auto angle_in_rad(T const &t)
+ -> decltype(std::atan2(std::imag(t), std::real(t)));
+ }
+#define NUMPY_NARY_FUNC_NAME angle_in_rad
+#define NUMPY_NARY_FUNC_SYM wrapper::angle_in_rad
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/any.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/any.hpp
new file mode 100644
index 00000000000..2add8b04052
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/any.hpp
@@ -0,0 +1,41 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ANY_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ANY_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/numpy/add.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ typename std::enable_if<types::is_numexpr_arg<E>::value, bool>::type
+ any(E const &expr, types::none_type _ = types::none_type());
+
+ template <class E>
+ typename std::enable_if<
+ std::is_scalar<E>::value || types::is_complex<E>::value, bool>::type
+ any(E const &expr, types::none_type _ = types::none_type());
+
+ template <class E>
+ auto any(E const &array, long axis) ->
+ typename std::enable_if<std::is_scalar<E>::value ||
+ types::is_complex<E>::value,
+ decltype(any(array))>::type;
+
+ template <class E>
+ auto any(E const &array, long axis) ->
+ typename std::enable_if<E::value == 1, decltype(any(array))>::type;
+
+ template <class E>
+ typename std::enable_if<
+ E::value != 1,
+ types::ndarray<typename E::dtype, types::array<long, E::value - 1>>>::type
+ any(E const &array, long axis);
+
+ DEFINE_FUNCTOR(pythonic::numpy, any);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/append.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/append.hpp
new file mode 100644
index 00000000000..935ef25176a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/append.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_APPEND_HPP
+#define PYTHONIC_INCLUDE_NUMPY_APPEND_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS, class F>
+ typename std::enable_if<
+ !types::is_dtype<F>::value,
+ types::ndarray<
+ typename __combined<T, typename types::dtype_of<F>::type>::type,
+ types::pshape<long>>>::type
+ append(types::ndarray<T, pS> const &nto, F const &data);
+
+ template <class T, class pS, class F>
+ typename std::enable_if<
+ types::is_dtype<F>::value,
+ types::ndarray<
+ typename __combined<T, typename types::dtype_of<F>::type>::type,
+ types::pshape<long>>>::type
+ append(types::ndarray<T, pS> const &nto, F const &data);
+
+ template <class T, class F>
+ types::ndarray<typename __combined<typename types::dtype_of<T>::type,
+ typename types::dtype_of<F>::type>::type,
+ types::pshape<long>>
+ append(T const &to, F const &data);
+
+ DEFINE_FUNCTOR(pythonic::numpy, append);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/arange.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/arange.hpp
new file mode 100644
index 00000000000..0b6cb1bcb32
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/arange.hpp
@@ -0,0 +1,194 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ARANGE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ARANGE_HPP
+
+#include "pythonic/include/operator_/pos.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace details
+ {
+#ifdef USE_XSIMD
+ template <class T>
+ struct arange_simd_iterator {
+ using vector_type = xsimd::batch<T>;
+ vector_type curr_;
+ vector_type step_;
+ long index_;
+ arange_simd_iterator(T start, T step, long n)
+ : curr_(), step_(static_cast<T>(vector_type::size * step)),
+ index_(static_cast<long>(n / vector_type::size))
+ {
+ T from[vector_type::size];
+ for (size_t i = 0; i < vector_type::size; ++i)
+ from[i] = start + i * step;
+ curr_ = vector_type::load_unaligned(from);
+ }
+ vector_type operator*() const
+ {
+ return curr_;
+ }
+ arange_simd_iterator &operator++()
+ {
+ curr_ += step_;
+ ++index_;
+ return *this;
+ }
+ arange_simd_iterator &operator+=(long n)
+ {
+ curr_ += n * step_;
+ index_ += n;
+ return *this;
+ }
+ arange_simd_iterator operator+(long n) const
+ {
+ arange_simd_iterator other{*this};
+ return other += n;
+ }
+ arange_simd_iterator &operator--()
+ {
+ curr_ -= step_;
+ --index_;
+ return *this;
+ }
+ long operator-(arange_simd_iterator const &other) const
+ {
+ return index_ - other.index_;
+ }
+ bool operator!=(arange_simd_iterator const &other) const
+ {
+ return index_ != other.index_;
+ }
+ bool operator==(arange_simd_iterator const &other) const
+ {
+ return index_ == other.index_;
+ }
+ bool operator<(arange_simd_iterator const &other) const
+ {
+ return index_ < other.index_;
+ }
+ arange_simd_iterator &
+ operator=(arange_simd_iterator const &other) = default;
+ };
+#endif
+ template <class T>
+ struct arange_index {
+ T start, step;
+ long size;
+ using iterator = types::nditerator<arange_index>;
+ using const_iterator = types::const_nditerator<arange_index>;
+ using dtype = T;
+ using value_type = dtype;
+ using shape_t = types::pshape<long>;
+#ifdef USE_XSIMD
+ using simd_iterator = arange_simd_iterator<T>;
+ using simd_iterator_nobroadcast = simd_iterator;
+ template <class vectorizer>
+ simd_iterator vbegin(vectorizer) const
+ {
+ return {start, step, 0};
+ }
+ template <class vectorizer>
+ simd_iterator vend(vectorizer) const
+ {
+ return {static_cast<T>(start + size * step), step, size};
+ }
+#endif
+ static constexpr size_t value = 1;
+ static constexpr bool is_strided = false;
+ static constexpr bool is_vectorizable = types::is_vectorizable<T>::value;
+
+ T fast(long i) const
+ {
+ return start + i * step;
+ }
+
+ dtype load(long i) const
+ {
+ return fast(i);
+ }
+
+ template <size_t I>
+ long shape() const
+ {
+ return size;
+ }
+ types::ndarray<dtype, shape_t> operator[](types::slice s) const
+ {
+ auto ns = s.normalize(size);
+ arange_index r{start + s.lower * step, step * ns.step, ns.size()};
+ return {
+ types::numpy_expr<pythonic::operator_::functor::pos, arange_index>{
+ r}};
+ }
+ types::ndarray<dtype, shape_t> operator()(types::slice s) const
+ {
+ return operator[](s);
+ }
+
+ template <long stride>
+ types::ndarray<dtype, shape_t>
+ operator[](types::cstride_slice<stride> s) const
+ {
+ auto ns = s.normalize(size);
+ arange_index r{start + s.lower * step, step * stride, ns.size()};
+ return {
+ types::numpy_expr<pythonic::operator_::functor::pos, arange_index>{
+ r}};
+ }
+
+ template <long stride>
+ types::ndarray<dtype, shape_t>
+ operator()(types::cstride_slice<stride> s) const
+ {
+ return operator[](s);
+ }
+
+ template <class... S>
+ auto operator()(S const &...s) const -> typename std::enable_if<
+ (sizeof...(S) > 1),
+ decltype(std::declval<types::ndarray<dtype, shape_t>>()(s...))>::type
+ {
+ return types::ndarray<dtype, shape_t>{
+ types::numpy_expr<pythonic::operator_::functor::pos, arange_index>{
+ *this}}(s...);
+ }
+ const_iterator begin() const
+ {
+ return {*this, 0};
+ }
+ const_iterator end() const
+ {
+ return {*this, size};
+ }
+
+ iterator begin()
+ {
+ return {*this, 0};
+ }
+ iterator end()
+ {
+ return {*this, size};
+ }
+ };
+ } // namespace details
+
+ template <class T, class U, class S = long,
+ class dtype = types::dtype_t<typename __combined<T, U, S>::type>>
+ types::numpy_expr<pythonic::operator_::functor::pos,
+ details::arange_index<typename dtype::type>>
+ arange(T begin, U end, S step = S(1), dtype d = dtype());
+
+ template <class T>
+ types::numpy_expr<pythonic::operator_::functor::pos,
+ details::arange_index<typename types::dtype_t<T>::type>>
+ arange(T end);
+
+ DEFINE_FUNCTOR(pythonic::numpy, arange);
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/arccos.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/arccos.hpp
new file mode 100644
index 00000000000..9c6745408af
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/arccos.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ARCCOS_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ARCCOS_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME arccos
+#define NUMPY_NARY_FUNC_SYM xsimd::acos
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/arccosh.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/arccosh.hpp
new file mode 100644
index 00000000000..8d1e7695aef
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/arccosh.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ARCCOSH_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ARCCOSH_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME arccosh
+#define NUMPY_NARY_FUNC_SYM xsimd::acosh
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/arcsin.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/arcsin.hpp
new file mode 100644
index 00000000000..849bead8022
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/arcsin.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ARCSIN_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ARCSIN_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME arcsin
+#define NUMPY_NARY_FUNC_SYM xsimd::asin
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/arcsinh.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/arcsinh.hpp
new file mode 100644
index 00000000000..94922c939c9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/arcsinh.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ARCSINH_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ARCSINH_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME arcsinh
+#define NUMPY_NARY_FUNC_SYM xsimd::asinh
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/arctan.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/arctan.hpp
new file mode 100644
index 00000000000..fb44c56b94d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/arctan.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ARCTAN_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ARCTAN_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME arctan
+#define NUMPY_NARY_FUNC_SYM xsimd::atan
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/arctan2/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/arctan2/accumulate.hpp
new file mode 100644
index 00000000000..e380b04855a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/arctan2/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ARCTAN2_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ARCTAN2_ACCUMULATE_HPP
+
+#define UFUNC_NAME arctan2
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/arctanh.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/arctanh.hpp
new file mode 100644
index 00000000000..ebf4a20807f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/arctanh.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ARCTANH_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ARCTANH_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME arctanh
+#define NUMPY_NARY_FUNC_SYM xsimd::atanh
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/argmax.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/argmax.hpp
new file mode 100644
index 00000000000..1bc9c5522c7
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/argmax.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ARGMAX_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ARGMAX_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class E>
+ long argmax(E const &expr);
+
+ template <class E>
+ types::ndarray<long, types::array<long, E::value - 1>> argmax(E const &expr,
+ long axis);
+
+ DEFINE_FUNCTOR(pythonic::numpy, argmax);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/argmin.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/argmin.hpp
new file mode 100644
index 00000000000..429a168fd39
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/argmin.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ARGMIN_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ARGMIN_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ long argmin(E const &expr);
+
+ template <class E>
+ types::ndarray<long, types::array<long, E::value - 1>> argmin(E const &expr,
+ long axis);
+
+ DEFINE_FUNCTOR(pythonic::numpy, argmin);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/argsort.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/argsort.hpp
new file mode 100644
index 00000000000..d7c3a189ebc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/argsort.hpp
@@ -0,0 +1,30 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ARGSORT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ARGSORT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ types::ndarray<long, types::array<long, 1>> argsort(E const &expr,
+ types::none_type,
+ types::none_type={});
+
+ template <class T, class pS>
+ types::ndarray<long, pS> argsort(types::ndarray<T, pS> const &a,
+ long axis = -1, types::none_type kind={});
+
+ template <class T, class pS>
+ types::ndarray<long, pS> argsort(types::ndarray<T, pS> const &a,
+ long axis, types::str const& kind);
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(argsort);
+
+ DEFINE_FUNCTOR(pythonic::numpy, argsort);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/argwhere.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/argwhere.hpp
new file mode 100644
index 00000000000..c69144a76f9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/argwhere.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ARGWHERE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ARGWHERE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ typename types::ndarray<long, types::array<long, 2>> argwhere(E const &expr);
+
+ DEFINE_FUNCTOR(pythonic::numpy, argwhere);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/around.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/around.hpp
new file mode 100644
index 00000000000..d79a3deff9c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/around.hpp
@@ -0,0 +1,46 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_AROUND_HPP
+#define PYTHONIC_INCLUDE_NUMPY_AROUND_HPP
+
+#include "pythonic/include/numpy/rint.hpp"
+#include "pythonic/include/numpy/floor_divide.hpp"
+#include "pythonic/include/numpy/asarray.hpp"
+#include "pythonic/include/numpy/float64.hpp"
+#include "pythonic/include/numpy/multiply.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ // fast path
+ template <class E>
+ auto around(E &&a) -> decltype(functor::rint{}(std::forward<E>(a)));
+
+ // generic floating point version, pure numpy_expr
+ template <class E>
+ auto around(E &&a, long decimals) -> typename std::enable_if<
+ !std::is_integral<
+ typename types::dtype_of<typename std::decay<E>::type>::type>::value,
+ decltype(functor::rint{}(functor::multiply{}(
+ std::forward<E>(a),
+ std::declval<typename types::dtype_of<
+ typename std::decay<E>::type>::type>())) /
+ std::declval<typename types::dtype_of<
+ typename std::decay<E>::type>::type>())>::type;
+
+ // the integer version is only relevant when decimals < 0
+ template <class E>
+ auto around(E &&a, long decimals) -> typename std::enable_if<
+ std::is_integral<
+ typename types::dtype_of<typename std::decay<E>::type>::type>::value,
+ decltype(numpy::functor::floor_divide{}(
+ functor::float64{}(std::forward<E>(a)),
+ std::declval<typename types::dtype_of<
+ typename std::decay<E>::type>::type>()) *
+ std::declval<typename types::dtype_of<
+ typename std::decay<E>::type>::type>())>::type;
+
+ DEFINE_FUNCTOR(pythonic::numpy, around);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/array2string.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/array2string.hpp
new file mode 100644
index 00000000000..29d2b4960b2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/array2string.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ARRAY2STRING_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ARRAY2STRING_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/str.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ types::str array2string(E &&a);
+
+ DEFINE_FUNCTOR(pythonic::numpy, array2string);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/array_equal.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/array_equal.hpp
new file mode 100644
index 00000000000..617598aef7b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/array_equal.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ARRAYEQUAL_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ARRAYEQUAL_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class U, class V>
+ bool array_equal(U const &u, V const &v);
+
+ DEFINE_FUNCTOR(pythonic::numpy, array_equal);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/array_equiv.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/array_equiv.hpp
new file mode 100644
index 00000000000..1ea7c520282
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/array_equiv.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ARRAYEQUIV_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ARRAYEQUIV_HPP
+
+#include "pythonic/include/numpy/array_equal.hpp"
+#include "pythonic/include/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class U, class V>
+ typename std::enable_if<U::value == V::value, bool>::type
+ array_equiv(U const &u, V const &v);
+
+ template <class U, class V>
+ typename std::enable_if <
+ U::value<V::value, bool>::type array_equiv(U const &u, V const &v);
+
+ template <class U, class V>
+ typename std::enable_if<(U::value > V::value), bool>::type
+ array_equiv(U const &u, V const &v);
+
+ DEFINE_FUNCTOR(pythonic::numpy, array_equiv);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/array_split.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/array_split.hpp
new file mode 100644
index 00000000000..d425c02e2e0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/array_split.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ARRAYSPLIT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ARRAYSPLIT_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ types::list<typename assignable<
+ decltype(std::declval<E>()[types::fast_contiguous_slice()])>::type>
+ array_split(E const &a, long nb_split);
+
+ template <class E, class I>
+ typename std::enable_if<
+ types::is_iterable<I>::value,
+ types::list<typename assignable<
+ decltype(std::declval<E>()[types::fast_contiguous_slice()])>::type>>::
+ type
+ array_split(E const &a, I const &split_mask);
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(array_split);
+ DEFINE_FUNCTOR(pythonic::numpy, array_split);
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/array_str.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/array_str.hpp
new file mode 100644
index 00000000000..3779c9c93c1
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/array_str.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ARRAYSTR_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ARRAYSTR_HPP
+
+#include "pythonic/include/numpy/array2string.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ USING_FUNCTOR(array_str, array2string);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/asarray_chkfinite.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/asarray_chkfinite.hpp
new file mode 100644
index 00000000000..f028e6419ff
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/asarray_chkfinite.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ASARRAYCHKFINITE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ASARRAYCHKFINITE_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/numpy/isfinite.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace wrapper
+ {
+ template <class I>
+ I asarray_chkfinite(I const &a);
+ }
+
+#define NUMPY_NARY_FUNC_NAME asarray_chkfinite
+#define NUMPY_NARY_FUNC_SYM wrapper::asarray_chkfinite
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ascontiguousarray.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ascontiguousarray.hpp
new file mode 100644
index 00000000000..587fbf52625
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ascontiguousarray.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ASCONTIGUOUSARRAY_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ASCONTIGUOUSARRAY_HPP
+
+#include "pythonic/include/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ USING_FUNCTOR(ascontiguousarray, asarray);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/asscalar.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/asscalar.hpp
new file mode 100644
index 00000000000..b35c22cafed
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/asscalar.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ASSCALAR_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ASSCALAR_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T>
+ using asscalar_result_type = typename std::conditional<
+ std::is_integral<T>::value, long,
+ typename std::conditional<std::is_floating_point<T>::value, double,
+ std::complex<double>>::type>::type;
+
+ template <class E>
+ asscalar_result_type<typename E::dtype> asscalar(E const &expr);
+
+ DEFINE_FUNCTOR(pythonic::numpy, asscalar);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/atleast_1d.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/atleast_1d.hpp
new file mode 100644
index 00000000000..ed73f588f55
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/atleast_1d.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ATLEAST1D_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ATLEAST1D_HPP
+
+#include "pythonic/include/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T>
+ typename std::enable_if<
+ types::is_dtype<T>::value,
+ types::ndarray<T, types::pshape<std::integral_constant<long, 1>>>>::type
+ atleast_1d(T t);
+
+ template <class T>
+ auto atleast_1d(T const &t) ->
+ typename std::enable_if<!(types::is_dtype<T>::value),
+ decltype(asarray(t))>::type;
+
+ DEFINE_FUNCTOR(pythonic::numpy, atleast_1d);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/atleast_2d.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/atleast_2d.hpp
new file mode 100644
index 00000000000..4e22a00ce22
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/atleast_2d.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ATLEAST2D_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ATLEAST2D_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T>
+ typename std::enable_if<
+ types::is_dtype<T>::value,
+ types::ndarray<T, types::pshape<std::integral_constant<long, 1>,
+ std::integral_constant<long, 1>>>>::type
+ atleast_2d(T t);
+
+ template <class T>
+ auto atleast_2d(T const &t) ->
+ typename std::enable_if < (!types::is_dtype<T>::value) &&
+ T::value<2, types::ndarray<
+ typename T::dtype,
+ types::pshape<std::integral_constant<long, 1>,
+ typename std::tuple_element<
+ 0, typename T::shape_t>::type>>>::type;
+
+ template <class T>
+ auto atleast_2d(T &&t) -> typename std::enable_if<
+ (!types::is_dtype<typename std::remove_cv<
+ typename std::remove_reference<T>::type>::type>::value) &&
+ std::decay<T>::type::value >= 2,
+ decltype(std::forward<T>(t))>::type;
+
+ DEFINE_FUNCTOR(pythonic::numpy, atleast_2d);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/atleast_3d.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/atleast_3d.hpp
new file mode 100644
index 00000000000..b5755733d12
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/atleast_3d.hpp
@@ -0,0 +1,45 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ATLEAST3D_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ATLEAST3D_HPP
+
+#include "pythonic/include/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T>
+ typename std::enable_if<
+ types::is_dtype<T>::value,
+ types::ndarray<T, types::pshape<std::integral_constant<long, 1>,
+ std::integral_constant<long, 1>,
+ std::integral_constant<long, 1>>>>::type
+ atleast_3d(T t);
+ template <class T>
+ auto atleast_3d(T const &t) -> typename std::enable_if<
+ (!types::is_dtype<T>::value) && (T::value == 1),
+ types::ndarray<typename T::dtype,
+ types::pshape<std::integral_constant<long, 1>,
+ typename std::tuple_element<
+ 0, typename T::shape_t>::type,
+ std::integral_constant<long, 1>>>>::type;
+
+ template <class T>
+ auto atleast_3d(T const &t) -> typename std::enable_if<
+ (!types::is_dtype<T>::value) && (T::value == 2),
+ types::ndarray<
+ typename T::dtype,
+ types::pshape<
+ typename std::tuple_element<0, typename T::shape_t>::type,
+ typename std::tuple_element<1, typename T::shape_t>::type,
+ std::integral_constant<long, 1>>>>::type;
+
+ template <class T>
+ auto atleast_3d(T const &t) ->
+ typename std::enable_if<(!types::is_dtype<T>::value) && T::value >= 3,
+ decltype(asarray(t))>::type;
+
+ DEFINE_FUNCTOR(pythonic::numpy, atleast_3d);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/average.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/average.hpp
new file mode 100644
index 00000000000..fd932195206
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/average.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_AVERAGE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_AVERAGE_HPP
+
+#include "pythonic/include/numpy/asarray.hpp"
+#include "pythonic/include/numpy/sum.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ auto average(E const &expr, types::none_type const &axis = builtins::None)
+ -> decltype(sum(expr, axis) / 1.);
+
+ template <class E>
+ auto average(E const &expr, long axis) -> decltype(sum(expr, axis) / 1.);
+
+ template <class E, class W>
+ auto average(E const &expr, types::none_type const &axis, W const &weights)
+ -> decltype(average(expr *asarray(weights) / average(asarray(weights))));
+
+ DEFINE_FUNCTOR(pythonic::numpy, average);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/base_repr.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/base_repr.hpp
new file mode 100644
index 00000000000..f102143ef1f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/base_repr.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_BASEREPR_HPP
+#define PYTHONIC_INCLUDE_NUMPY_BASEREPR_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ types::str base_repr(long number, long base = 2, long padding = 0);
+
+ DEFINE_FUNCTOR(pythonic::numpy, base_repr);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/binary_repr.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/binary_repr.hpp
new file mode 100644
index 00000000000..f6bb382f7dd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/binary_repr.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_BINARYREPR_HPP
+#define PYTHONIC_INCLUDE_NUMPY_BINARYREPR_HPP
+
+#include "pythonic/include/numpy/base_repr.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ types::str binary_repr(long number, types::none_type width = builtins::None);
+
+ types::str binary_repr(long number, long width);
+
+ DEFINE_FUNCTOR(pythonic::numpy, binary_repr);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/bincount.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/bincount.hpp
new file mode 100644
index 00000000000..24022fd35c7
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/bincount.hpp
@@ -0,0 +1,33 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_BINCOUNT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_BINCOUNT_HPP
+
+#include "pythonic/include/numpy/max.hpp"
+#include "pythonic/include/utils/numpy_conversion.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS>
+ typename std::enable_if<std::tuple_size<pS>::value == 1,
+ types::ndarray<long, types::pshape<long>>>::type
+ bincount(types::ndarray<T, pS> const &expr,
+ types::none_type weights = builtins::None,
+ types::none<long> minlength = builtins::None);
+
+ template <class T, class E, class pS>
+ typename std::enable_if<
+ std::tuple_size<pS>::value == 1,
+ types::ndarray<decltype(std::declval<long>() *
+ std::declval<typename E::dtype>()),
+ types::pshape<long>>>::type
+ bincount(types::ndarray<T, pS> const &expr, E const &weights,
+ types::none<long> minlength = builtins::None);
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(bincount);
+
+ DEFINE_FUNCTOR(pythonic::numpy, bincount);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_and.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_and.hpp
new file mode 100644
index 00000000000..f4389ca83a2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_and.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_BITWISE_AND_HPP
+#define PYTHONIC_INCLUDE_NUMPY_BITWISE_AND_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/operator_/and_.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME bitwise_and
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::and_
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_and/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_and/accumulate.hpp
new file mode 100644
index 00000000000..72a33782590
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_and/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_BITWISE_AND_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_BITWISE_AND_ACCUMULATE_HPP
+
+#define UFUNC_NAME bitwise_and
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_and/reduce.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_and/reduce.hpp
new file mode 100644
index 00000000000..3c668de465f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_and/reduce.hpp
@@ -0,0 +1,10 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_BITWISE_AND_REDUCE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_BITWISE_AND_REDUCE_HPP
+
+#define UFUNC_NAME bitwise_and
+#define UFUNC_INAME iand
+#include "pythonic/include/numpy/ufunc_reduce.hpp"
+#undef UFUNC_NAME
+#undef UFUNC_INAME
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_or.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_or.hpp
new file mode 100644
index 00000000000..be50b626d87
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_or.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_BITWISE_OR_HPP
+#define PYTHONIC_INCLUDE_NUMPY_BITWISE_OR_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/operator_/or_.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME bitwise_or
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::or_
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_or/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_or/accumulate.hpp
new file mode 100644
index 00000000000..dfb62ffe740
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_or/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_BITWISE_OR_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_BITWISE_OR_ACCUMULATE_HPP
+
+#define UFUNC_NAME bitwise_or
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_or/reduce.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_or/reduce.hpp
new file mode 100644
index 00000000000..3bf35028dfb
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_or/reduce.hpp
@@ -0,0 +1,10 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_BITWISE_OR_REDUCE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_BITWISE_OR_REDUCE_HPP
+
+#define UFUNC_NAME bitwise_or
+#define UFUNC_INAME ior
+#include "pythonic/include/numpy/ufunc_reduce.hpp"
+#undef UFUNC_NAME
+#undef UFUNC_INAME
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_xor.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_xor.hpp
new file mode 100644
index 00000000000..9324d6d5427
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_xor.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_BITWISE_XOR_HPP
+#define PYTHONIC_INCLUDE_NUMPY_BITWISE_XOR_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/operator_/xor_.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME bitwise_xor
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::xor_
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_xor/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_xor/accumulate.hpp
new file mode 100644
index 00000000000..02a5c9a26ca
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_xor/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_BITWISE_XOR_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_BITWISE_XOR_ACCUMULATE_HPP
+
+#define UFUNC_NAME bitwise_xor
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_xor/reduce.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_xor/reduce.hpp
new file mode 100644
index 00000000000..11ba083c434
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/bitwise_xor/reduce.hpp
@@ -0,0 +1,10 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_BITWISE_XOR_REDUCE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_BITWISE_XOR_REDUCE_HPP
+
+#define UFUNC_NAME bitwise_xor
+#define UFUNC_INAME ixor
+#include "pythonic/include/numpy/ufunc_reduce.hpp"
+#undef UFUNC_NAME
+#undef UFUNC_INAME
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/broadcast_to.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/broadcast_to.hpp
new file mode 100644
index 00000000000..122c43c6ab0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/broadcast_to.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_BROADCAST_TO_HPP
+#define PYTHONIC_INCLUDE_NUMPY_BROADCAST_TO_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/numpy/empty.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E, class pS>
+ auto broadcast_to(E const &expr, pS shape)
+ -> decltype(numpy::functor::empty{}(
+ shape, typename types::dtype_t<typename types::dtype_of<E>::type>{}));
+
+ DEFINE_FUNCTOR(pythonic::numpy, broadcast_to);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/byte.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/byte.hpp
new file mode 100644
index 00000000000..79f388e5aad
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/byte.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_BYTE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_BYTE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/meta.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/types/numpy_op_helper.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ char byte();
+ template <class V>
+ char byte(V v);
+ }
+
+#define NUMPY_NARY_FUNC_NAME byte
+#define NUMPY_NARY_FUNC_SYM details::byte
+#define NUMPY_NARY_EXTRA_METHOD using type = char;
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/cbrt.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/cbrt.hpp
new file mode 100644
index 00000000000..b78a05ee1af
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/cbrt.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_CBRT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_CBRT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME cbrt
+#define NUMPY_NARY_FUNC_SYM xsimd::cbrt
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/clip.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/clip.hpp
new file mode 100644
index 00000000000..610b2146734
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/clip.hpp
@@ -0,0 +1,51 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_CLIP_HPP
+#define PYTHONIC_INCLUDE_NUMPY_CLIP_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ // special private handler for clip(v, None, m) {
+
+#define NUMPY_NARY_FUNC_NAME _clip_max
+#define NUMPY_NARY_FUNC_SYM xsimd::min
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+
+ // }
+
+ namespace wrapper
+ {
+ template <class T, class Mi, class Ma>
+ typename __combined<T, Mi, Ma>::type clip(T const &v, Mi a_min, Ma a_max);
+
+ template <class T, class Mi>
+ typename __combined<T, Mi>::type clip(T const &v, Mi a_min);
+ }
+
+#define NUMPY_NARY_FUNC_NAME clip
+#define NUMPY_NARY_FUNC_SYM wrapper::clip
+#define NUMPY_NARY_EXTRA_METHOD \
+ template <typename T, class Mi> \
+ auto operator()(T &&v, Mi &&a_min, types::none_type) \
+ ->decltype((*this)(std::forward<T>(v), std::forward<Mi>(a_min))) \
+ { \
+ return (*this)(std::forward<T>(v), std::forward<Mi>(a_min)); \
+ } \
+ template <typename T, class Ma> \
+ auto operator()(T &&v, types::none_type, Ma &&a_max) \
+ ->decltype(_clip_max{}(std::forward<T>(v), std::forward<Ma>(a_max))) \
+ { \
+ return _clip_max{}(std::forward<T>(v), std::forward<Ma>(a_max)); \
+ }
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/complex.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/complex.hpp
new file mode 100644
index 00000000000..5d14999e4dd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/complex.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_COMPLEX_HPP
+#define PYTHONIC_INCLUDE_NUMPY_COMPLEX_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/complex.hpp"
+#include "pythonic/include/utils/meta.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/types/numpy_op_helper.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace details
+ {
+
+ std::complex<double> complex(double v = 0, double v2 = 0.);
+ }
+
+#define NUMPY_NARY_FUNC_NAME complex
+#define NUMPY_NARY_FUNC_SYM details::complex
+#define NUMPY_NARY_EXTRA_METHOD using type = std::complex<double>;
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/concatenate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/concatenate.hpp
new file mode 100644
index 00000000000..8ce663f0bf2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/concatenate.hpp
@@ -0,0 +1,30 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_CONCATENATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_CONCATENATE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E, size_t M, class V>
+ types::ndarray<typename E::dtype, types::array<long, E::value>>
+ concatenate(types::array_base<E, M, V> const &args, long axis = 0);
+
+ template <class... Types>
+ auto concatenate(std::tuple<Types...> const &args, long axis = 0)
+ -> types::ndarray<
+ typename __combined<typename std::decay<Types>::type::dtype...>::type,
+ types::array<
+ long, std::tuple_element<0, std::tuple<Types...>>::type::value>>;
+
+ template <class E>
+ types::ndarray<typename E::dtype, types::array<long, E::value>>
+ concatenate(types::list<E> const &args, long axis = 0);
+
+ DEFINE_FUNCTOR(pythonic::numpy, concatenate);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/convolve.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/convolve.hpp
new file mode 100644
index 00000000000..b87fa07d51d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/convolve.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_CONVOLVE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_CONVOLVE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class A, class B, typename U>
+ types::ndarray<typename A::dtype, types::pshape<long>>
+ convolve(A const &inA, B const &inB, U renorm = types::str("full"));
+
+ template <class A, class B>
+ types::ndarray<typename A::dtype, types::pshape<long>> convolve(A const &inA,
+ B const &inB);
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(convolve)
+ DEFINE_FUNCTOR(pythonic::numpy, convolve)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/copy.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/copy.hpp
new file mode 100644
index 00000000000..891b562bd2c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/copy.hpp
@@ -0,0 +1,43 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_COPY_HPP
+#define PYTHONIC_INCLUDE_NUMPY_COPY_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_conversion.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ // list case
+ template <class E>
+ typename std::enable_if<
+ !types::is_array<E>::value && !types::is_dtype<E>::value,
+ types::ndarray<typename E::dtype, types::array<long, E::value>>>::type
+ copy(E const &v);
+
+ // scalar / complex case
+ template <class E>
+ auto copy(E const &v) ->
+ typename std::enable_if<types::is_dtype<E>::value, E>::type;
+
+ // No copy is required for numpy_expr
+ template <class E>
+ auto copy(E &&v) ->
+ typename std::enable_if<types::is_array<E>::value,
+ decltype(std::forward<E>(v))>::type;
+
+ // ndarray case
+ template <class T, class pS>
+ types::ndarray<T, pS> copy(types::ndarray<T, pS> const &a);
+
+ // transposed ndarray case
+ template <class T, class pS>
+ types::numpy_texpr<types::ndarray<T, pS>>
+ copy(types::numpy_texpr<types::ndarray<T, pS>> const &a);
+
+ DEFINE_FUNCTOR(pythonic::numpy, copy);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/copysign.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/copysign.hpp
new file mode 100644
index 00000000000..bafe162931c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/copysign.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_COPYSIGN_HPP
+#define PYTHONIC_INCLUDE_NUMPY_COPYSIGN_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME copysign
+#define NUMPY_NARY_FUNC_SYM xsimd::copysign
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/copysign/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/copysign/accumulate.hpp
new file mode 100644
index 00000000000..fe4f26af3e9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/copysign/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_COPYSIGN_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_COPYSIGN_ACCUMULATE_HPP
+
+#define UFUNC_NAME copysign
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/correlate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/correlate.hpp
new file mode 100644
index 00000000000..8a33eec0ade
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/correlate.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_CORRELATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_CORRELATE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class A, class B>
+ types::ndarray<typename A::dtype, types::pshape<long>>
+ correlate(A const &inA, B const &inB,
+ types::str const &renorm = types::str("valid"));
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(correlate)
+ DEFINE_FUNCTOR(pythonic::numpy, correlate)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/cosh.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/cosh.hpp
new file mode 100644
index 00000000000..d028a6a12a3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/cosh.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_COSH_HPP
+#define PYTHONIC_INCLUDE_NUMPY_COSH_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME cosh
+#define NUMPY_NARY_FUNC_SYM xsimd::cosh
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/count_nonzero.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/count_nonzero.hpp
new file mode 100644
index 00000000000..748511e8080
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/count_nonzero.hpp
@@ -0,0 +1,30 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_COUNT_NONZERO_HPP
+#define PYTHONIC_INCLUDE_NUMPY_COUNT_NONZERO_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class dtype, class E>
+ auto _count_nonzero(E begin, E end, long &count, utils::int_<1>) ->
+ typename std::enable_if<std::is_same<dtype, bool>::value>::type;
+
+ template <class dtype, class E>
+ auto _count_nonzero(E begin, E end, long &count, utils::int_<1>) ->
+ typename std::enable_if<!std::is_same<dtype, bool>::value>::type;
+
+ template <class dtype, class E, size_t N>
+ void _count_nonzero(E begin, E end, long &count, utils::int_<N>);
+
+ template <class E>
+ long count_nonzero(E const &array);
+
+ DEFINE_FUNCTOR(pythonic::numpy, count_nonzero);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/cross.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/cross.hpp
new file mode 100644
index 00000000000..3f12a70544e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/cross.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_CROSS_HPP
+#define PYTHONIC_INCLUDE_NUMPY_CROSS_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E, class F>
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::array<long, E::value>>
+ cross(E const &e, F const &f);
+
+ DEFINE_FUNCTOR(pythonic::numpy, cross);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ctypeslib/as_array.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ctypeslib/as_array.hpp
new file mode 100644
index 00000000000..d804c6d958f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ctypeslib/as_array.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_CTYPESLIB_AS_ARRAY_HPP
+#define PYTHONIC_INCLUDE_NUMPY_CTYPESLIB_AS_ARRAY_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/pointer.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace ctypeslib
+ {
+ template <class T, class pS>
+ typename std::enable_if<!std::is_integral<pS>::value,
+ types::ndarray<T, pS>>::type
+ as_array(types::pointer<T>, pS);
+
+ template <class T>
+ types::ndarray<T, types::pshape<long>> as_array(types::pointer<T>, long);
+ DEFINE_FUNCTOR(pythonic::numpy::ctypeslib, as_array);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/cumprod.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/cumprod.hpp
new file mode 100644
index 00000000000..a3bbd2cf98d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/cumprod.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_CUMPROD_HPP
+#define PYTHONIC_INCLUDE_NUMPY_CUMPROD_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/numpy/partial_sum.hpp"
+#include "pythonic/include/operator_/imul.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class E, class... Opts>
+ auto cumprod(E &&e, Opts &&... opts)
+ -> decltype(partial_sum<operator_::functor::imul>(
+ std::forward<E>(e), std::forward<Opts>(opts)...));
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(cumprod);
+
+ DEFINE_FUNCTOR(pythonic::numpy, cumprod);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/cumproduct.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/cumproduct.hpp
new file mode 100644
index 00000000000..52a23357de7
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/cumproduct.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_CUMPRODUCT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_CUMPRODUCT_HPP
+
+#include "pythonic/include/numpy/cumprod.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ USING_FUNCTOR(cumproduct, cumprod);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/cumsum.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/cumsum.hpp
new file mode 100644
index 00000000000..8f16278a4a0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/cumsum.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_CUMSUM_HPP
+#define PYTHONIC_INCLUDE_NUMPY_CUMSUM_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/numpy/partial_sum.hpp"
+#include "pythonic/include/operator_/iadd.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class E, class... Opts>
+ auto cumsum(E &&e, Opts &&... opts)
+ -> decltype(partial_sum<operator_::functor::add>(
+ std::forward<E>(e), std::forward<Opts>(opts)...));
+
+ DEFINE_FUNCTOR(pythonic::numpy, cumsum);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/deg2rad.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/deg2rad.hpp
new file mode 100644
index 00000000000..b104663b38f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/deg2rad.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_DEG2RAD_HPP
+#define PYTHONIC_INCLUDE_NUMPY_DEG2RAD_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/numpy/pi.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T>
+ auto deg2rad(T const &val) -> decltype(val *pi / 180)
+ {
+ return val * pi / 180;
+ }
+ }
+#define NUMPY_NARY_FUNC_NAME deg2rad
+#define NUMPY_NARY_FUNC_SYM wrapper::deg2rad
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/degrees.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/degrees.hpp
new file mode 100644
index 00000000000..2e2edb275fe
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/degrees.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_DEGREES_HPP
+#define PYTHONIC_INCLUDE_NUMPY_DEGREES_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/numpy/rad2deg.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ USING_FUNCTOR(degrees, rad2deg);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/delete_.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/delete_.hpp
new file mode 100644
index 00000000000..ebdbd409df4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/delete_.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_DELETE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_DELETE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS>
+ types::ndarray<T, types::pshape<long>>
+ delete_(types::ndarray<T, pS> const &a, long index,
+ types::none_type axis = builtins::None);
+
+ template <class T, class pS, class I>
+ typename std::enable_if<!std::is_scalar<I>::value,
+ types::ndarray<T, types::pshape<long>>>::type
+ delete_(types::ndarray<T, pS> const &in, I const &indices,
+ types::none_type axis = builtins::None);
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(delete_);
+ DEFINE_FUNCTOR(pythonic::numpy, delete_);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/diag.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/diag.hpp
new file mode 100644
index 00000000000..3f4e20f836d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/diag.hpp
@@ -0,0 +1,32 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_DIAG_HPP
+#define PYTHONIC_INCLUDE_NUMPY_DIAG_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_conversion.hpp"
+#include "pythonic/include/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS>
+ typename std::enable_if<std::tuple_size<pS>::value == 2,
+ types::ndarray<T, types::pshape<long>>>::type
+ diag(types::ndarray<T, pS> const &a, long k = 0);
+
+ template <class T, class pS>
+ typename std::enable_if<std::tuple_size<pS>::value == 1,
+ types::ndarray<T, types::array<long, 2>>>::type
+ diag(types::ndarray<T, pS> const &a, long k = 0);
+
+ template <class T>
+ auto diag(types::list<T> const &a, long k = 0)
+ -> decltype(diag(asarray(a), k));
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(diag);
+ DEFINE_FUNCTOR(pythonic::numpy, diag);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/diagflat.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/diagflat.hpp
new file mode 100644
index 00000000000..8d88be64185
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/diagflat.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_DIAGFLAT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_DIAGFLAT_HPP
+
+#include "pythonic/include/numpy/diag.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ USING_FUNCTOR(diagflat, diag);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/diagonal.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/diagonal.hpp
new file mode 100644
index 00000000000..0d27215a7c1
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/diagonal.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_DIAGONAL_HPP
+#define PYTHONIC_INCLUDE_NUMPY_DIAGONAL_HPP
+
+#include "pythonic/include/numpy/diag.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ USING_FUNCTOR(diagonal, diag);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/diff.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/diff.hpp
new file mode 100644
index 00000000000..2498aa53198
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/diff.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_DIFF_HPP
+#define PYTHONIC_INCLUDE_NUMPY_DIFF_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class E>
+ types::ndarray<typename E::dtype, types::array<long, E::value>>
+ diff(E const &expr, long n = 1, long axis = -1);
+
+ DEFINE_FUNCTOR(pythonic::numpy, diff);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/digitize.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/digitize.hpp
new file mode 100644
index 00000000000..08ff40a6dd1
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/digitize.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_DIGITIZE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_DIGITIZE_HPP
+
+#include "pythonic/include/numpy/asarray.hpp"
+#include "pythonic/include/builtins/None.hpp"
+#include "pythonic/include/operator_/gt.hpp"
+#include "pythonic/include/operator_/lt.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E, class F>
+ types::ndarray<long, types::pshape<long>> digitize(E const &expr, F const &b);
+
+ DEFINE_FUNCTOR(pythonic::numpy, digitize);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/divide.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/divide.hpp
new file mode 100644
index 00000000000..4b296246f57
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/divide.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_DIVIDE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_DIVIDE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/operator_/div.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME divide
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::div
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/divide/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/divide/accumulate.hpp
new file mode 100644
index 00000000000..74f88bb28b6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/divide/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_DIVIDE_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_DIVIDE_ACCUMULATE_HPP
+
+#define UFUNC_NAME divide
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/dot.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/dot.hpp
new file mode 100644
index 00000000000..a8dc8089a82
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/dot.hpp
@@ -0,0 +1,284 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_DOT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_DOT_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/numpy/sum.hpp"
+#include "pythonic/include/types/numpy_expr.hpp"
+#include "pythonic/include/types/traits.hpp"
+
+template <class T>
+struct is_blas_type : pythonic::types::is_complex<T> {
+};
+
+template <>
+struct is_blas_type<float> : std::true_type {
+};
+
+template <>
+struct is_blas_type<double> : std::true_type {
+};
+
+template <class E>
+struct is_strided {
+ template <class T>
+ static decltype(T::is_strided, std::true_type{}) get(T *);
+ static std::false_type get(...);
+ static constexpr bool value = decltype(get((E *)nullptr))::value;
+};
+
+template <class E>
+struct is_blas_array {
+ // FIXME: also support gexpr with stride?
+ static constexpr bool value =
+ pythonic::types::is_array<E>::value &&
+ is_blas_type<pythonic::types::dtype_of<E>>::value &&
+ !is_strided<E>::value;
+};
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E, class F>
+ typename std::enable_if<types::is_dtype<E>::value &&
+ types::is_dtype<F>::value,
+ decltype(std::declval<E>() * std::declval<F>())>::type
+ dot(E const &e, F const &f);
+
+ /// Vector / Vector multiplication
+ template <class E, class F>
+ typename std::enable_if<
+ types::is_numexpr_arg<E>::value && types::is_numexpr_arg<F>::value &&
+ E::value == 1 && F::value == 1 &&
+ (!is_blas_array<E>::value || !is_blas_array<F>::value ||
+ !std::is_same<typename E::dtype, typename F::dtype>::value),
+ typename __combined<typename E::dtype, typename F::dtype>::type>::type
+ dot(E const &e, F const &f);
+
+ template <class E, class F>
+ typename std::enable_if<E::value == 1 && F::value == 1 &&
+ std::is_same<typename E::dtype, float>::value &&
+ std::is_same<typename F::dtype, float>::value &&
+ is_blas_array<E>::value &&
+ is_blas_array<F>::value,
+ float>::type
+ dot(E const &e, F const &f);
+
+ template <class E, class F>
+ typename std::enable_if<E::value == 1 && F::value == 1 &&
+ std::is_same<typename E::dtype, double>::value &&
+ std::is_same<typename F::dtype, double>::value &&
+ is_blas_array<E>::value &&
+ is_blas_array<F>::value,
+ double>::type
+ dot(E const &e, F const &f);
+
+ template <class E, class F>
+ typename std::enable_if<
+ E::value == 1 && F::value == 1 &&
+ std::is_same<typename E::dtype, std::complex<float>>::value &&
+ std::is_same<typename F::dtype, std::complex<float>>::value &&
+ is_blas_array<E>::value && is_blas_array<F>::value,
+ std::complex<float>>::type
+ dot(E const &e, F const &f);
+
+ template <class E, class F>
+ typename std::enable_if<
+ E::value == 1 && F::value == 1 &&
+ std::is_same<typename E::dtype, std::complex<double>>::value &&
+ std::is_same<typename F::dtype, std::complex<double>>::value &&
+ is_blas_array<E>::value && is_blas_array<F>::value,
+ std::complex<double>>::type
+ dot(E const &e, F const &f);
+
+ /// Matrix / Vector multiplication
+
+ // We transpose the matrix to reflect our C order
+ template <class E, class pS0, class pS1>
+ typename std::enable_if<is_blas_type<E>::value &&
+ std::tuple_size<pS0>::value == 2 &&
+ std::tuple_size<pS1>::value == 1,
+ types::ndarray<E, types::pshape<long>>>::type
+ dot(types::ndarray<E, pS0> const &f, types::ndarray<E, pS1> const &e);
+
+ template <class E, class pS0, class pS1>
+ typename std::enable_if<is_blas_type<E>::value &&
+ std::tuple_size<pS0>::value == 2 &&
+ std::tuple_size<pS1>::value == 1,
+ types::ndarray<E, types::pshape<long>>>::type
+ dot(types::numpy_texpr<types::ndarray<E, pS0>> const &f,
+ types::ndarray<E, pS1> const &e);
+
+ // The trick is to not transpose the matrix so that MV become VM
+ template <class E, class pS0, class pS1>
+ typename std::enable_if<is_blas_type<E>::value &&
+ std::tuple_size<pS0>::value == 1 &&
+ std::tuple_size<pS1>::value == 2,
+ types::ndarray<E, types::pshape<long>>>::type
+ dot(types::ndarray<E, pS0> const &e, types::ndarray<E, pS1> const &f);
+
+ template <class E, class pS0, class pS1>
+ typename std::enable_if<is_blas_type<E>::value &&
+ std::tuple_size<pS0>::value == 1 &&
+ std::tuple_size<pS1>::value == 2,
+ types::ndarray<E, types::pshape<long>>>::type
+ dot(types::ndarray<E, pS0> const &e,
+ types::numpy_texpr<types::ndarray<E, pS1>> const &f);
+
+ // If arguments could be use with blas, we evaluate them as we need pointer
+ // on array for blas
+ template <class E, class F>
+ typename std::enable_if<
+ types::is_numexpr_arg<E>::value &&
+ types::is_numexpr_arg<F>::value // It is an array_like
+ && (!(types::is_ndarray<E>::value && types::is_ndarray<F>::value) ||
+ !std::is_same<typename E::dtype, typename F::dtype>::value) &&
+ is_blas_type<typename E::dtype>::value &&
+ is_blas_type<typename F::dtype>::value // With dtype compatible with
+ // blas
+ &&
+ E::value == 2 && F::value == 1, // And it is matrix / vect
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::pshape<long>>>::type
+ dot(E const &e, F const &f);
+
+ // If arguments could be use with blas, we evaluate them as we need pointer
+ // on array for blas
+ template <class E, class F>
+ typename std::enable_if<
+ types::is_numexpr_arg<E>::value &&
+ types::is_numexpr_arg<F>::value // It is an array_like
+ && (!(types::is_ndarray<E>::value && types::is_ndarray<F>::value) ||
+ !std::is_same<typename E::dtype, typename F::dtype>::value) &&
+ is_blas_type<typename E::dtype>::value &&
+ is_blas_type<typename F::dtype>::value // With dtype compatible with
+ // blas
+ &&
+ E::value == 1 && F::value == 2, // And it is vect / matrix
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::pshape<long>>>::type
+ dot(E const &e, F const &f);
+
+ // If one of the arg doesn't have a "blas compatible type", we use a slow
+ // matrix vector multiplication.
+ template <class E, class F>
+ typename std::enable_if<
+ (!is_blas_type<typename E::dtype>::value ||
+ !is_blas_type<typename F::dtype>::value) &&
+ E::value == 1 && F::value == 2, // And it is vect / matrix
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::pshape<long>>>::type
+ dot(E const &e, F const &f);
+
+ // If one of the arg doesn't have a "blas compatible type", we use a slow
+ // matrix vector multiplication.
+ template <class E, class F>
+ typename std::enable_if<
+ (!is_blas_type<typename E::dtype>::value ||
+ !is_blas_type<typename F::dtype>::value) &&
+ E::value == 2 && F::value == 1, // And it is vect / matrix
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::pshape<long>>>::type
+ dot(E const &e, F const &f);
+
+ /// Matrix / Matrix multiplication
+
+ // The trick is to use the transpose arguments to reflect C order.
+ // We want to perform A * B in C order but blas order is F order.
+ // So we compute B'A' == (AB)'. As this equality is perform with F order
+ // We doesn't have to return a texpr because we want a C order matrice!!
+ template <class E, class pS0, class pS1>
+ typename std::enable_if<is_blas_type<E>::value &&
+ std::tuple_size<pS0>::value == 2 &&
+ std::tuple_size<pS1>::value == 2,
+ types::ndarray<E, types::array<long, 2>>>::type
+ dot(types::ndarray<E, pS0> const &a, types::ndarray<E, pS1> const &b);
+
+ template <class E, class pS0, class pS1, class pS2>
+ typename std::enable_if<
+ is_blas_type<E>::value && std::tuple_size<pS0>::value == 2 &&
+ std::tuple_size<pS1>::value == 2 && std::tuple_size<pS2>::value == 2,
+ types::ndarray<E, pS2>>::type &
+ dot(types::ndarray<E, pS0> const &a, types::ndarray<E, pS1> const &b,
+ types::ndarray<E, pS2> &c);
+
+ // texpr variants: MT, TM, TT
+ template <class E, class pS0, class pS1>
+ typename std::enable_if<is_blas_type<E>::value &&
+ std::tuple_size<pS0>::value == 2 &&
+ std::tuple_size<pS1>::value == 2,
+ types::ndarray<E, types::array<long, 2>>>::type
+ dot(types::numpy_texpr<types::ndarray<E, pS0>> const &a,
+ types::ndarray<E, pS1> const &b);
+ template <class E, class pS0, class pS1>
+ typename std::enable_if<is_blas_type<E>::value &&
+ std::tuple_size<pS0>::value == 2 &&
+ std::tuple_size<pS1>::value == 2,
+ types::ndarray<E, types::array<long, 2>>>::type
+ dot(types::ndarray<E, pS0> const &a,
+ types::numpy_texpr<types::ndarray<E, pS1>> const &b);
+ template <class E, class pS0, class pS1>
+ typename std::enable_if<is_blas_type<E>::value &&
+ std::tuple_size<pS0>::value == 2 &&
+ std::tuple_size<pS1>::value == 2,
+ types::ndarray<E, types::array<long, 2>>>::type
+ dot(types::numpy_texpr<types::ndarray<E, pS0>> const &a,
+ types::numpy_texpr<types::ndarray<E, pS1>> const &b);
+
+ // If arguments could be use with blas, we evaluate them as we need pointer
+ // on array for blas
+ template <class E, class F>
+ typename std::enable_if<
+ types::is_numexpr_arg<E>::value &&
+ types::is_numexpr_arg<F>::value // It is an array_like
+ && (!(types::is_ndarray<E>::value && types::is_ndarray<F>::value) ||
+ !std::is_same<typename E::dtype, typename F::dtype>::value) &&
+ is_blas_type<typename E::dtype>::value &&
+ is_blas_type<typename F::dtype>::value // With dtype compatible with
+ // blas
+ &&
+ E::value == 2 && F::value == 2, // And both are matrix
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::array<long, 2>>>::type
+ dot(E const &e, F const &f);
+
+ // If one of the arg doesn't have a "blas compatible type", we use a slow
+ // matrix multiplication.
+ template <class E, class F>
+ typename std::enable_if<
+ (!is_blas_type<typename E::dtype>::value ||
+ !is_blas_type<typename F::dtype>::value) &&
+ E::value == 2 && F::value == 2, // And it is matrix / matrix
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::array<long, 2>>>::type
+ dot(E const &e, F const &f);
+
+ // N x M where N >= 3 and M == 1
+ template <class E, class F>
+ typename std::enable_if<
+ (E::value >= 3 && F::value == 1),
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::array<long, E::value - 1>>>::type
+ dot(E const &e, F const &f);
+
+ // N x M where N >= 3 and M >= 2
+ template <class E, class F>
+ typename std::enable_if<
+ (E::value >= 3 && F::value >= 2),
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::array<long, E::value - 1>>>::type
+ dot(E const &e, F const &f);
+
+ DEFINE_FUNCTOR(pythonic::numpy, dot);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/double_.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/double_.hpp
new file mode 100644
index 00000000000..3fd626d6e86
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/double_.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_DOUBLE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_DOUBLE_HPP
+
+#include "pythonic/include/numpy/float64.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME double_
+#define NUMPY_NARY_FUNC_SYM details::float64
+#define NUMPY_NARY_EXTRA_METHOD using type = double;
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/dtype/type.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/dtype/type.hpp
new file mode 100644
index 00000000000..004d17dee5f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/dtype/type.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_DTYPE_TYPE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_DTYPE_TYPE_HPP
+#include "pythonic/include/utils/functor.hpp"
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace dtype
+ {
+ template <class T, class V>
+ auto type(T const &t, V const &v) -> decltype(t(v));
+ DEFINE_FUNCTOR(pythonic::numpy::dtype, type);
+ }
+}
+
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/e.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/e.hpp
new file mode 100644
index 00000000000..aa28eeb3338
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/e.hpp
@@ -0,0 +1,12 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_E_HPP
+#define PYTHONIC_INCLUDE_NUMPY_E_HPP
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ double constexpr e = 2.718281828459045235360287471352662498;
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ediff1d.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ediff1d.hpp
new file mode 100644
index 00000000000..07c653f58bd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ediff1d.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_EDIFF1D_HPP
+#define PYTHONIC_INCLUDE_NUMPY_EDIFF1D_HPP
+
+#include "pythonic/include/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ types::ndarray<typename E::dtype, types::pshape<long>> ediff1d(E const &expr);
+
+ template <class E>
+ auto ediff1d(types::list<E> const &expr) -> decltype(ediff1d(asarray(expr)));
+
+ DEFINE_FUNCTOR(pythonic::numpy, ediff1d);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/equal.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/equal.hpp
new file mode 100644
index 00000000000..8057acad764
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/equal.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_EQUAL_HPP
+#define PYTHONIC_INCLUDE_NUMPY_EQUAL_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/operator_/eq.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME equal
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::eq
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/equal/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/equal/accumulate.hpp
new file mode 100644
index 00000000000..852ddcbdba2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/equal/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_EQUAL_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_EQUAL_ACCUMULATE_HPP
+
+#define UFUNC_NAME equal
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/expm1.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/expm1.hpp
new file mode 100644
index 00000000000..c755bc6460b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/expm1.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_EXPM1_HPP
+#define PYTHONIC_INCLUDE_NUMPY_EXPM1_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME expm1
+#define NUMPY_NARY_FUNC_SYM xsimd::expm1
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/eye.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/eye.hpp
new file mode 100644
index 00000000000..54da451b1b1
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/eye.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_EYE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_EYE_HPP
+
+#include "pythonic/include/numpy/zeros.hpp"
+#include "pythonic/include/numpy/float64.hpp"
+#include "pythonic/include/builtins/None.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class dtype = functor::float64>
+ types::ndarray<typename dtype::type, types::array<long, 2>>
+ eye(long N, long M, long k = 0, dtype d = dtype());
+
+ template <class dtype = functor::float64>
+ types::ndarray<typename dtype::type, types::array<long, 2>>
+ eye(long N, types::none_type M = builtins::None, long k = 0,
+ dtype d = dtype());
+
+ DEFINE_FUNCTOR(pythonic::numpy, eye);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fabs.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fabs.hpp
new file mode 100644
index 00000000000..64d6b4c49b2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fabs.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FABS_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FABS_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/numpy/abs.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ USING_FUNCTOR(fabs, numpy::functor::abs);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fft/c2c.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fft/c2c.hpp
new file mode 100644
index 00000000000..50efdbe4a59
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fft/c2c.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FFT_C2C_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FFT_C2C_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace fft
+ {
+
+ template <class T, class pS>
+ types::ndarray<std::complex<T>,
+ types::array<long, std::tuple_size<pS>::value>>
+ c2c(types::ndarray<std::complex<T>, pS> const &a, long n = -1,
+ long axis = -1, types::str const &norm = {}, bool const forward = true);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fft/fft.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fft/fft.hpp
new file mode 100644
index 00000000000..faa4b0488ab
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fft/fft.hpp
@@ -0,0 +1,55 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FFT_FFT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FFT_FFT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+/**
+ * **Noteable difference to numpy.fft.fft:**
+ * In contrast to numpy.fft.fft this implementation preserves precision
+ * of floating point and complex inputs, i.e. complex<float> input yields
+ * complex<float> output. numpy.fft.fft always returns complex<double>, even for
+ * long double input. This follows the same reasoning as given by numpy compiled
+ * with intel_mkl (see here: https://github.com/IntelPython/mkl_fft/issues/10).
+ * Conversion to double precision causes code to be slower and hurts use cases
+ * where single precision preservation is desired, e.g. when interacting with
+ *GPUs
+ * or instruments. Moreover for the case of long double inputs, this avoids
+ * loss of precision.
+ **/
+
+namespace numpy
+{
+ namespace fft
+ {
+
+ template <class T, class pS, class N = types::none_type, class Norm = types::none_type>
+ types::ndarray<
+ typename std::enable_if<types::is_complex<T>::value, T>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ fft(types::ndarray<T, pS> const &a, N const & n = {}, long axis = -1,
+ Norm const &norm = {});
+
+ template <class T, class pS, class N = types::none_type, class Norm = types::none_type>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ fft(types::ndarray<T, pS> const &a, N const & n = {}, long axis = -1,
+ Norm const &norm = {});
+
+ template <class T, class pS, class N = types::none_type, class Norm = types::none_type>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ fft(types::ndarray<T, pS> const &a, N const & n = {}, long axis = -1,
+ Norm const &norm = {});
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(fft);
+ DEFINE_FUNCTOR(pythonic::numpy::fft, fft);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fft/fftn.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fft/fftn.hpp
new file mode 100644
index 00000000000..c4c3561caff
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fft/fftn.hpp
@@ -0,0 +1,69 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FFT_FFTN_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FFT_FFTN_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace fft
+ {
+ // without shape
+ template <class T, class pS, class Axes = types::none_type,
+ class Norm = types::none_type>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ fftn(types::ndarray<T, pS> const &a, types::none_type s = {},
+ Axes const &axes = {}, Norm const &norm = {});
+
+ template <class T, class pS, class Axes = types::none_type,
+ class Norm = types::none_type>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ fftn(types::ndarray<T, pS> const &a, types::none_type s = {},
+ Axes const &axes = {}, Norm const &norm = {});
+
+ template <class T, class pS, class Axes = types::none_type,
+ class Norm = types::none_type>
+ types::ndarray<
+ typename std::enable_if<types::is_complex<T>::value, T>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ fftn(types::ndarray<T, pS> const &a, types::none_type s = {},
+ Axes const &axes = {}, Norm const &norm = {});
+
+ // with shape
+ template <class T, class pS, class I, size_t N, class V,
+ class Axes = types::none_type, class Norm = types::none_type>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ fftn(types::ndarray<T, pS> const &a, types::array_base<I, N, V> const &s,
+ Axes const &axes = {}, Norm const &norm = {});
+
+ template <class T, class pS, class I, size_t N, class V,
+ class Axes = types::none_type, class Norm = types::none_type>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ fftn(types::ndarray<T, pS> const &a, types::array_base<I, N, V> const &s,
+ Axes const &axes = {}, Norm const &norm = {});
+
+ template <class T, class pS, class I, size_t N, class V,
+ class Axes = types::none_type, class Norm = types::none_type>
+ types::ndarray<
+ typename std::enable_if<types::is_complex<T>::value, T>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ fftn(types::ndarray<T, pS> const &a, types::array_base<I, N, V> const &s,
+ Axes const &axes = {}, Norm const &norm = {});
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(fftn);
+ DEFINE_FUNCTOR(pythonic::numpy::fft, fftn);
+ } // namespace fft
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fft/hfft.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fft/hfft.hpp
new file mode 100644
index 00000000000..38b06fd511f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fft/hfft.hpp
@@ -0,0 +1,90 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FFT_HFFT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FFT_HFFT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+/**
+ * **Noteable difference to numpy.fft.hfft:**
+ * In contrast to numpy.fft.hfft this implementation preserves precision
+ * of floating point and complex inputs, i.e. complex<float> input yields
+ * complex<float> output. numpy.fft.fft always returns complex<double>, even for
+ * long double input. This follows the same reasoning as given by numpy compiled
+ * with intel_mkl (see here: https://github.com/IntelPython/mkl_fft/issues/10).
+ * Conversion to double precision causes code to be slower and hurts use cases
+ * where single precision preservation is desired, e.g. when interacting with
+ *GPUs
+ * or instruments. Moreover for the case of long double inputs, this avoids
+ * loss of precision.
+ **/
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace fft
+ {
+
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ hfft(types::ndarray<std::complex<T>, pS> const &a, long n = -1,
+ long axis = -1, types::str const &norm = {});
+
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ hfft(types::ndarray<std::complex<T>, pS> const &a, types::none_type n,
+ long axis, types::str const &norm);
+
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ hfft(types::ndarray<std::complex<T>, pS> const &a, long n, long axis,
+ types::none_type norm);
+
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ hfft(types::ndarray<std::complex<T>, pS> const &a, types::none_type n,
+ long axis = -1, types::none_type norm = types::none_type{});
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<
+ !types::is_complex<T>::value,
+ typename std::conditional<std::is_integral<T>::value,
+ double, T>::type>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ hfft(types::ndarray<T, pS> const &a, long n = -1, long axis = -1,
+ types::str const &norm = {});
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<
+ !types::is_complex<T>::value,
+ typename std::conditional<std::is_integral<T>::value,
+ double, T>::type>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ hfft(types::ndarray<T, pS> const &a, types::none_type n, long axis,
+ types::str const &norm);
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<
+ !types::is_complex<T>::value,
+ typename std::conditional<std::is_integral<T>::value,
+ double, T>::type>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ hfft(types::ndarray<T, pS> const &a, long n, long axis,
+ types::none_type norm);
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<
+ !types::is_complex<T>::value,
+ typename std::conditional<std::is_integral<T>::value,
+ double, T>::type>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ hfft(types::ndarray<T, pS> const &a, types::none_type n, long axis = -1,
+ types::none_type norm = types::none_type{});
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(hfft);
+ DEFINE_FUNCTOR(pythonic::numpy::fft, hfft);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fft/ifft.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fft/ifft.hpp
new file mode 100644
index 00000000000..24f6bfa88cd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fft/ifft.hpp
@@ -0,0 +1,118 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FFT_IFFT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FFT_IFFT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+/**
+ * **Noteable difference to numpy.fft.ifft:**
+ * In contrast to numpy.fft.fft this implementation preserves precision
+ * of floating point and complex inputs, i.e. complex<float> input yields
+ * complex<float> output. numpy.fft.fft always returns complex<double>, even for
+ * long double input. This follows the same reasoning as given by numpy compiled
+ * with intel_mkl (see here: https://github.com/IntelPython/mkl_fft/issues/10).
+ * Conversion to double precision causes code to be slower and hurts use cases
+ * where single precision preservation is desired, e.g. when interacting with
+ *GPUs
+ * or instruments. Moreover for the case of long double inputs, this avoids
+ * loss of precision.
+ **/
+
+namespace numpy
+{
+ namespace fft
+ {
+
+ template <class T, class pS>
+ types::ndarray<
+ typename std::enable_if<types::is_complex<T>::value, T>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &a, long n = -1, long axis = -1,
+ types::str const &norm = {});
+
+ template <class T, class pS>
+ types::ndarray<
+ typename std::enable_if<types::is_complex<T>::value, T>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &a, types::none_type n, long axis,
+ types::str const &norm);
+
+ template <class T, class pS>
+ types::ndarray<
+ typename std::enable_if<types::is_complex<T>::value, T>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &a, long n, long axis,
+ types::none_type norm);
+
+ template <class T, class pS>
+ types::ndarray<
+ typename std::enable_if<types::is_complex<T>::value, T>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &a, types::none_type n, long axis = -1,
+ types::none_type norm = types::none_type{});
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &a, long n = -1, long axis = -1,
+ types::str const &norm = {});
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &a, types::none_type n, long axis,
+ types::str const &norm);
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &a, long n, long axis,
+ types::none_type norm);
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &a, types::none_type n, long axis = -1,
+ types::none_type norm = types::none_type{});
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &a, long n = -1, long axis = -1,
+ types::str const &norm = {});
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &a, types::none_type n, long axis,
+ types::str const &norm);
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &a, long n, long axis,
+ types::none_type norm);
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &a, types::none_type n, long axis = -1,
+ types::none_type norm = types::none_type{});
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(ifft);
+ DEFINE_FUNCTOR(pythonic::numpy::fft, ifft);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fft/ihfft.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fft/ihfft.hpp
new file mode 100644
index 00000000000..6512191907f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fft/ihfft.hpp
@@ -0,0 +1,90 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FFT_IHFFT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FFT_IHFFT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+/**
+ * **Noteable difference to numpy.fft.ihfft:**
+ * In contrast to numpy.fft.ihfft this implementation preserves precision
+ * of floating point and complex inputs, i.e. complex<float> input yields
+ * complex<float> output. numpy.fft.fft always returns complex<double>, even for
+ * long double input. This follows the same reasoning as given by numpy compiled
+ * with intel_mkl (see here: https://github.com/IntelPython/mkl_fft/issues/10).
+ * Conversion to double precision causes code to be slower and hurts use cases
+ * where single precision preservation is desired, e.g. when interacting with
+ *GPUs
+ * or instruments. Moreover for the case of long double inputs, this avoids
+ * loss of precision.
+ **/
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace fft
+ {
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ihfft(types::ndarray<T, pS> const &a, long n = -1, long axis = -1,
+ types::str const &norm = {});
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ihfft(types::ndarray<T, pS> const &a, types::none_type n, long axis,
+ types::str const &norm);
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ihfft(types::ndarray<T, pS> const &a, long n, long axis,
+ types::none_type norm);
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ihfft(types::ndarray<T, pS> const &a, types::none_type n, long axis = -1,
+ types::none_type norm = types::none_type{});
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ihfft(types::ndarray<T, pS> const &a, long n = -1, long axis = -1,
+ types::str const &norm = {});
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ihfft(types::ndarray<T, pS> const &a, types::none_type n, long axis,
+ types::str const &norm);
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ihfft(types::ndarray<T, pS> const &a, long n, long axis,
+ types::none_type norm);
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ihfft(types::ndarray<T, pS> const &a, types::none_type n, long axis = -1,
+ types::none_type norm = types::none_type{});
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(ihfft);
+ DEFINE_FUNCTOR(pythonic::numpy::fft, ihfft);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fft/irfft.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fft/irfft.hpp
new file mode 100644
index 00000000000..2ec0ac26b3b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fft/irfft.hpp
@@ -0,0 +1,90 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FFT_IRFFT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FFT_IRFFT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+/**
+ * **Noteable difference to numpy.fft.irfft:**
+ * In contrast to numpy.fft.irfft this implementation preserves precision
+ * of floating point and complex inputs, i.e. complex<float> input yields
+ * complex<float> output. numpy.fft.fft always returns complex<double>, even for
+ * long double input. This follows the same reasoning as given by numpy compiled
+ * with intel_mkl (see here: https://github.com/IntelPython/mkl_fft/issues/10).
+ * Conversion to double precision causes code to be slower and hurts use cases
+ * where single precision preservation is desired, e.g. when interacting with
+ *GPUs
+ * or instruments. Moreover for the case of long double inputs, this avoids
+ * loss of precision.
+ **/
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace fft
+ {
+
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ irfft(types::ndarray<std::complex<T>, pS> const &a, long n = -1,
+ long axis = -1, types::str const &norm = {});
+
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ irfft(types::ndarray<std::complex<T>, pS> const &a, types::none_type n,
+ long axis, types::str const &norm);
+
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ irfft(types::ndarray<std::complex<T>, pS> const &a, long n, long axis,
+ types::none_type norm);
+
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ irfft(types::ndarray<std::complex<T>, pS> const &a, types::none_type n,
+ long axis = -1, types::none_type norm = types::none_type{});
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<
+ !types::is_complex<T>::value,
+ typename std::conditional<std::is_integral<T>::value,
+ double, T>::type>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ irfft(types::ndarray<T, pS> const &a, long n = -1, long axis = -1,
+ types::str const &norm = {});
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<
+ !types::is_complex<T>::value,
+ typename std::conditional<std::is_integral<T>::value,
+ double, T>::type>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ irfft(types::ndarray<T, pS> const &a, types::none_type n, long axis,
+ types::str const &norm);
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<
+ !types::is_complex<T>::value,
+ typename std::conditional<std::is_integral<T>::value,
+ double, T>::type>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ irfft(types::ndarray<T, pS> const &a, long n, long axis,
+ types::none_type norm);
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<
+ !types::is_complex<T>::value,
+ typename std::conditional<std::is_integral<T>::value,
+ double, T>::type>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ irfft(types::ndarray<T, pS> const &a, types::none_type n, long axis = -1,
+ types::none_type norm = types::none_type{});
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(irfft);
+ DEFINE_FUNCTOR(pythonic::numpy::fft, irfft);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fft/rfft.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fft/rfft.hpp
new file mode 100644
index 00000000000..2125ab17644
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fft/rfft.hpp
@@ -0,0 +1,90 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FFT_RFFT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FFT_RFFT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+/**
+ * **Noteable difference to numpy.fft.rfft:**
+ * In contrast to numpy.fft.rfft this implementation preserves precision
+ * of floating point and complex inputs, i.e. complex<float> input yields
+ * complex<float> output. numpy.fft.fft always returns complex<double>, even for
+ * long double input. This follows the same reasoning as given by numpy compiled
+ * with intel_mkl (see here: https://github.com/IntelPython/mkl_fft/issues/10).
+ * Conversion to double precision causes code to be slower and hurts use cases
+ * where single precision preservation is desired, e.g. when interacting with
+ *GPUs
+ * or instruments. Moreover for the case of long double inputs, this avoids
+ * loss of precision.
+ **/
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace fft
+ {
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ rfft(types::ndarray<T, pS> const &a, long n = -1, long axis = -1,
+ types::str const &norm = {});
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ rfft(types::ndarray<T, pS> const &a, types::none_type n, long axis,
+ types::str const &norm);
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ rfft(types::ndarray<T, pS> const &a, long n, long axis,
+ types::none_type norm);
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ rfft(types::ndarray<T, pS> const &a, types::none_type n, long axis = -1,
+ types::none_type norm = types::none_type{});
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ rfft(types::ndarray<T, pS> const &a, long n = -1, long axis = -1,
+ types::str const &norm = {});
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ rfft(types::ndarray<T, pS> const &a, types::none_type n, long axis,
+ types::str const &norm);
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ rfft(types::ndarray<T, pS> const &a, long n, long axis,
+ types::none_type norm);
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ rfft(types::ndarray<T, pS> const &a, types::none_type n, long axis = -1,
+ types::none_type norm = types::none_type{});
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(rfft);
+ DEFINE_FUNCTOR(pythonic::numpy::fft, rfft);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fill_diagonal.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fill_diagonal.hpp
new file mode 100644
index 00000000000..94617bd027f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fill_diagonal.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FILL_DIAGONAL_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FILL_DIAGONAL_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ types::none_type fill_diagonal(E &&, typename std::decay<E>::type::dtype);
+
+ DEFINE_FUNCTOR(pythonic::numpy, fill_diagonal)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/finfo.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/finfo.hpp
new file mode 100644
index 00000000000..9bde7525406
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/finfo.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FINFO_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FINFO_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/numpy/float64.hpp"
+#include "pythonic/include/types/finfo.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class dtype = functor::float64>
+ types::finfo<typename dtype::type> finfo(dtype d = dtype());
+
+ DEFINE_FUNCTOR(pythonic::numpy, finfo)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fix.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fix.hpp
new file mode 100644
index 00000000000..2708930d6c8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fix.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FIX_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FIX_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME fix
+#define NUMPY_NARY_FUNC_SYM std::trunc
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/flatnonzero.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/flatnonzero.hpp
new file mode 100644
index 00000000000..a592be1df38
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/flatnonzero.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FLATNONZERO_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FLATNONZERO_HPP
+
+#include "pythonic/include/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ types::ndarray<long, types::pshape<long>> flatnonzero(E const &expr);
+
+ DEFINE_FUNCTOR(pythonic::numpy, flatnonzero);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/flip.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/flip.hpp
new file mode 100644
index 00000000000..cc22afce5af
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/flip.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FLIP_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FLIP_HPP
+
+#include "pythonic/include/types/numpy_gexpr.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_conversion.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace details
+ {
+ template <class E, class S, size_t... I>
+ auto flip(E const &expr, S const &slices, utils::index_sequence<I...>)
+ -> decltype(expr(slices[I]...));
+ }
+
+ template <class E>
+ auto flip(E const &expr, long axis)
+ -> decltype(details::flip(expr, std::array<types::slice, E::value>{},
+ utils::make_index_sequence<E::value>{}));
+
+ DEFINE_FUNCTOR(pythonic::numpy, flip);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fliplr.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fliplr.hpp
new file mode 100644
index 00000000000..c2738a93e88
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fliplr.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FLIPLR_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FLIPLR_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ auto fliplr(E &&expr) -> decltype(std::forward<E>(expr)(
+ types::cstride_slice<1>{builtins::None, builtins::None},
+ types::slice{builtins::None, builtins::None, -1}));
+
+ DEFINE_FUNCTOR(pythonic::numpy, fliplr);
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/flipud.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/flipud.hpp
new file mode 100644
index 00000000000..e02b76b4346
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/flipud.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FLIPUD_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FLIPUD_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ auto flipud(E &&expr) -> decltype(
+ std::forward<E>(expr)[types::slice{builtins::None, builtins::None, -1}]);
+
+ DEFINE_FUNCTOR(pythonic::numpy, flipud);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/float128.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/float128.hpp
new file mode 100644
index 00000000000..d1638ca45fc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/float128.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FLOAT128_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FLOAT128_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/types/numpy_op_helper.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace details
+ {
+
+ long double float128();
+ template <class V>
+ long double float128(V v);
+ }
+
+#define NUMPY_NARY_FUNC_NAME float128
+#define NUMPY_NARY_FUNC_SYM details::float128
+#define NUMPY_NARY_EXTRA_METHOD using type = long double;
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/float_.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/float_.hpp
new file mode 100644
index 00000000000..ed470a24c37
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/float_.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FLOAT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FLOAT_HPP
+
+#include "pythonic/include/numpy/float64.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME float_
+#define NUMPY_NARY_FUNC_SYM details::float64
+#define NUMPY_NARY_EXTRA_METHOD using type = double;
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/floor_divide/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/floor_divide/accumulate.hpp
new file mode 100644
index 00000000000..893bae552c5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/floor_divide/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FLOOR_DIVIDE_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FLOOR_DIVIDE_ACCUMULATE_HPP
+
+#define UFUNC_NAME floor_divide
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fmax.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fmax.hpp
new file mode 100644
index 00000000000..34fb398da36
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fmax.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FMAX_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FMAX_HPP
+
+#include "pythonic/include/numpy/maximum.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ USING_FUNCTOR(fmax, maximum);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fmax/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fmax/accumulate.hpp
new file mode 100644
index 00000000000..019a8758ded
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fmax/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FMAX_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FMAX_ACCUMULATE_HPP
+
+#define UFUNC_NAME fmax
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fmax/reduce.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fmax/reduce.hpp
new file mode 100644
index 00000000000..4fc6a0aefd0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fmax/reduce.hpp
@@ -0,0 +1,10 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FMAX_REDUCE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FMAX_REDUCE_HPP
+
+#define UFUNC_NAME fmax
+#define UFUNC_INAME imax
+#include "pythonic/include/numpy/ufunc_reduce.hpp"
+#undef UFUNC_NAME
+#undef UFUNC_INAME
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fmin.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fmin.hpp
new file mode 100644
index 00000000000..cd879cc6afb
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fmin.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FMIN_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FMIN_HPP
+
+#include "pythonic/include/numpy/minimum.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ USING_FUNCTOR(fmin, minimum);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fmin/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fmin/accumulate.hpp
new file mode 100644
index 00000000000..eaff505e313
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fmin/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FMIN_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FMIN_ACCUMULATE_HPP
+
+#define UFUNC_NAME fmin
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fmin/reduce.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fmin/reduce.hpp
new file mode 100644
index 00000000000..3042311e39b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fmin/reduce.hpp
@@ -0,0 +1,10 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FMIN_REDUCE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FMIN_REDUCE_HPP
+
+#define UFUNC_NAME fmin
+#define UFUNC_INAME imin
+#include "pythonic/include/numpy/ufunc_reduce.hpp"
+#undef UFUNC_NAME
+#undef UFUNC_INAME
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fmod.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fmod.hpp
new file mode 100644
index 00000000000..a7b3732c2fa
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fmod.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FMOD_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FMOD_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME fmod
+#define NUMPY_NARY_FUNC_SYM xsimd::fmod
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fmod/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fmod/accumulate.hpp
new file mode 100644
index 00000000000..5e7b2125bee
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fmod/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FMOD_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FMOD_ACCUMULATE_HPP
+
+#define UFUNC_NAME fmod
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/frexp.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/frexp.hpp
new file mode 100644
index 00000000000..6a894806026
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/frexp.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FREXP_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FREXP_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_conversion.hpp"
+#include "pythonic/include/types/traits.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T>
+ typename std::enable_if<std::is_scalar<T>::value, std::tuple<T, int>>::type
+ frexp(T val);
+
+ template <class E>
+ typename std::enable_if<
+ !types::is_dtype<E>::value,
+ std::tuple<types::ndarray<typename E::dtype, typename E::shape_t>,
+ types::ndarray<int, typename E::shape_t>>>::type
+ frexp(E const &arr);
+
+ DEFINE_FUNCTOR(pythonic::numpy, frexp);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fromfile.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fromfile.hpp
new file mode 100644
index 00000000000..62498964bdb
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fromfile.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FROMFILE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FROMFILE_HPP
+
+#include "pythonic/include/numpy/float64.hpp"
+#include "pythonic/include/types/list.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class dtype = functor::float64>
+ types::ndarray<typename dtype::type, types::pshape<long>>
+ fromfile(types::str const &file_name, dtype d = dtype(), long count = -1,
+ types::str const &sep = {}, long offset = 0);
+
+ DEFINE_FUNCTOR(pythonic::numpy, fromfile);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fromfunction.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fromfunction.hpp
new file mode 100644
index 00000000000..c4068d8a7fb
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fromfunction.hpp
@@ -0,0 +1,47 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FROMFUNCTION_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FROMFUNCTION_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/builtins/None.hpp"
+#include "pythonic/include/utils/tags.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class F, size_t N, class dtype, class Tags>
+ struct fromfunction_helper;
+
+ template <class F, class dtype, class purity_tag>
+ struct fromfunction_helper<F, 1, dtype, purity_tag> {
+ template <class pS>
+ types::ndarray<typename std::remove_cv<typename std::remove_reference<
+ typename std::result_of<F(dtype)>::type>::type>::type,
+ pS>
+ operator()(F &&f, pS const &shape, dtype d = dtype());
+ };
+
+ template <class F, class dtype, class purity_tag>
+ struct fromfunction_helper<F, 2, dtype, purity_tag> {
+ template <class pS>
+ types::ndarray<
+ typename std::remove_cv<typename std::remove_reference<
+ typename std::result_of<F(dtype, dtype)>::type>::type>::type,
+ pS>
+ operator()(F &&f, pS const &shape, dtype d = dtype());
+ };
+
+ template <class F, class pS, class dtype = double>
+ auto fromfunction(F &&f, pS const &shape, dtype d = dtype())
+ -> decltype(fromfunction_helper<F, std::tuple_size<pS>::value, dtype,
+ typename pythonic::purity_of<F>::type>()(
+ std::forward<F>(f), shape));
+
+ /* TODO: must specialize for higher order */
+ DEFINE_FUNCTOR(pythonic::numpy, fromfunction);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fromiter.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fromiter.hpp
new file mode 100644
index 00000000000..3c6009a2db4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fromiter.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FROMITER_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FROMITER_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/numpy/float64.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class Iterable, class dtype = functor::float64>
+ types::ndarray<typename std::remove_cv<typename std::remove_reference<
+ Iterable>::type>::type::value_type,
+ types::pshape<long>>
+ fromiter(Iterable &&iterable, dtype d = dtype(), long count = -1);
+
+ DEFINE_FUNCTOR(pythonic::numpy, fromiter);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/fromstring.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/fromstring.hpp
new file mode 100644
index 00000000000..38aeab73f38
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/fromstring.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FROMSTRING_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FROMSTRING_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/numpy/float64.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/list.hpp"
+#include "pythonic/include/types/str.hpp"
+
+#include <limits>
+#include <sstream>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class dtype = functor::float64>
+ types::ndarray<typename dtype::type, types::pshape<long>>
+ fromstring(types::str const &string, dtype d = dtype(), long count = -1,
+ types::str const &sep = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy, fromstring);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/full.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/full.hpp
new file mode 100644
index 00000000000..18deb0cb575
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/full.hpp
@@ -0,0 +1,42 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FULL_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FULL_HPP
+
+#include "pythonic/include/numpy/float64.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class pS, class F, class dtype>
+ types::ndarray<typename dtype::type, sutils::shape_t<pS>>
+ full(pS const &shape, F fill_value, dtype d);
+
+ template <class F, class dtype>
+ types::ndarray<typename dtype::type, types::pshape<long>>
+ full(long size, F fill_value, dtype d);
+
+ template <long N, class F, class dtype>
+ types::ndarray<typename dtype::type,
+ types::pshape<std::integral_constant<long, N>>>
+ full(std::integral_constant<long, N>, F fill_value, dtype d);
+
+ template <class pS, class F>
+ types::ndarray<F, sutils::shape_t<pS>> full(pS const &shape, F fill_value,
+ types::none_type _ = {});
+
+ template <class F>
+ types::ndarray<F, types::pshape<long>> full(long size, F fill_value,
+ types::none_type _ = {});
+
+ template <long N, class F>
+ types::ndarray<F, types::pshape<std::integral_constant<long, N>>>
+ full(std::integral_constant<long, N>, F fill_value, types::none_type _ = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy, full);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/full_like.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/full_like.hpp
new file mode 100644
index 00000000000..0c57174ed2f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/full_like.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_FULLLIKE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FULLLIKE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/numpy/full.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class E, class F, class dtype>
+ auto full_like(E const &expr, F fill_value, dtype d = dtype())
+ -> decltype(full(sutils::getshape(expr), fill_value, d));
+
+ template <class E, class F>
+ auto full_like(E const &expr, F fill_value,
+ types::none_type d = builtins::None)
+ -> decltype(full(sutils::getshape(expr), fill_value,
+ types::dtype_t<typename E::dtype>()));
+
+ DEFINE_FUNCTOR(pythonic::numpy, full_like)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/greater.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/greater.hpp
new file mode 100644
index 00000000000..e04f675ddac
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/greater.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_GREATER_HPP
+#define PYTHONIC_INCLUDE_NUMPY_GREATER_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/operator_/gt.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME greater
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::gt
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/greater/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/greater/accumulate.hpp
new file mode 100644
index 00000000000..729b04d0a12
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/greater/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_GREATER_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_GREATER_ACCUMULATE_HPP
+
+#define UFUNC_NAME greater
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/greater_equal.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/greater_equal.hpp
new file mode 100644
index 00000000000..7ab0b317457
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/greater_equal.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_GREATEREQUAL_HPP
+#define PYTHONIC_INCLUDE_NUMPY_GREATEREQUAL_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/operator_/ge.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME greater_equal
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::ge
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/greater_equal/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/greater_equal/accumulate.hpp
new file mode 100644
index 00000000000..f444996f82d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/greater_equal/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_GREATER_EQUAL_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_GREATER_EQUAL_ACCUMULATE_HPP
+
+#define UFUNC_NAME greater_equal
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/heaviside.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/heaviside.hpp
new file mode 100644
index 00000000000..1b7594b7f64
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/heaviside.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_HEAVISIDE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_HEAVISIDE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace details
+ {
+ template <class T0, class T1>
+ T1 heaviside(T0 x0, T1 x1);
+ }
+#define NUMPY_NARY_FUNC_NAME heaviside
+#define NUMPY_NARY_FUNC_SYM details::heaviside
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/heaviside/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/heaviside/accumulate.hpp
new file mode 100644
index 00000000000..57c781e5283
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/heaviside/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_HEAVISIDE_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_HEAVISIDE_ACCUMULATE_HPP
+
+#define UFUNC_NAME heaviside
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/hstack.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/hstack.hpp
new file mode 100644
index 00000000000..05ea492a4a1
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/hstack.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_HSTACK_HPP
+#define PYTHONIC_INCLUDE_NUMPY_HSTACK_HPP
+
+#include <pythonic/include/numpy/concatenate.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class ArraySequence>
+ auto hstack(ArraySequence &&seq)
+ -> decltype(concatenate(std::forward<ArraySequence>(seq), 1));
+
+ DEFINE_FUNCTOR(pythonic::numpy, hstack);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/hypot.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/hypot.hpp
new file mode 100644
index 00000000000..1f98eb076fd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/hypot.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_HYPOT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_HYPOT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME hypot
+#define NUMPY_NARY_FUNC_SYM xsimd::hypot
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/hypot/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/hypot/accumulate.hpp
new file mode 100644
index 00000000000..8a7c4a1f682
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/hypot/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_HYPOT_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_HYPOT_ACCUMULATE_HPP
+
+#define UFUNC_NAME hypot
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/identity.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/identity.hpp
new file mode 100644
index 00000000000..c506c11569d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/identity.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_IDENTITY_HPP
+#define PYTHONIC_INCLUDE_NUMPY_IDENTITY_HPP
+
+#include "pythonic/include/numpy/eye.hpp"
+#include "pythonic/include/numpy/float64.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class dtype = functor::float64>
+ auto identity(long n, dtype d = dtype()) -> decltype(eye(n, n, 0, d));
+
+ DEFINE_FUNCTOR(pythonic::numpy, identity);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/imag.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/imag.hpp
new file mode 100644
index 00000000000..93c772a1edc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/imag.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_IMAG_HPP
+#define PYTHONIC_INCLUDE_NUMPY_IMAG_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/numpy/asarray.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/list.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ auto imag(E &&expr) -> decltype(builtins::getattr(types::attr::IMAG{},
+ std::forward<E>(expr)));
+
+ template <class T>
+ auto imag(types::list<T> const &expr)
+ -> decltype(imag(numpy::functor::asarray{}(expr)));
+
+ DEFINE_FUNCTOR(pythonic::numpy, imag);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/indices.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/indices.hpp
new file mode 100644
index 00000000000..4fd613a66db
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/indices.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_INDICES_HPP
+#define PYTHONIC_INCLUDE_NUMPY_INDICES_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/numpy/int64.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class pS, class dtype = functor::int64>
+ types::ndarray<
+ typename dtype::type,
+ sutils::push_front_t<
+ pS, std::integral_constant<long, std::tuple_size<pS>::value>>>
+ indices(pS const &shape, dtype d = dtype());
+
+ DEFINE_FUNCTOR(pythonic::numpy, indices);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/inner.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/inner.hpp
new file mode 100644
index 00000000000..ac3b1b7c49a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/inner.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_INNER_HPP
+#define PYTHONIC_INCLUDE_NUMPY_INNER_HPP
+
+#include "pythonic/include/numpy/dot.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ USING_FUNCTOR(inner, dot);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/insert.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/insert.hpp
new file mode 100644
index 00000000000..af748c18d47
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/insert.hpp
@@ -0,0 +1,51 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_INSERT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_INSERT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/traits.hpp"
+#include "pythonic/include/builtins/None.hpp"
+
+#include <algorithm>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class T, class pS, class I, class F>
+ typename std::enable_if<types::is_iterable<I>::value &&
+ types::is_iterable<F>::value,
+ types::ndarray<T, types::pshape<long>>>::type
+ insert(types::ndarray<T, pS> in, I const &indices, F const &data,
+ types::none_type axis = builtins::None);
+
+ template <class T, class pS, class I, class F>
+ typename std::enable_if<types::is_iterable<I>::value &&
+ !types::is_iterable<F>::value,
+ types::ndarray<T, types::pshape<long>>>::type
+ insert(types::ndarray<T, pS> in, I const &indices, F const &data,
+ types::none_type axis = builtins::None);
+
+ template <class T, class pS, class I, class F>
+ typename std::enable_if<!types::is_iterable<I>::value &&
+ types::is_iterable<F>::value,
+ types::ndarray<T, types::pshape<long>>>::type
+ insert(types::ndarray<T, pS> in, I const &indices, F const &data,
+ types::none_type axis = builtins::None);
+
+ template <class T, class pS, class I, class F>
+ typename std::enable_if<!types::is_iterable<I>::value &&
+ !types::is_iterable<F>::value,
+ types::ndarray<T, types::pshape<long>>>::type
+ insert(types::ndarray<T, pS> in, I const &indices, F const &data,
+ types::none_type axis = builtins::None);
+
+ template <class E, class... Args>
+ E insert(E, Args const &...);
+
+ DEFINE_FUNCTOR(pythonic::numpy, insert);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/int_.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/int_.hpp
new file mode 100644
index 00000000000..57df3fe4b9c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/int_.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_INT__HPP
+#define PYTHONIC_INCLUDE_NUMPY_INT__HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/meta.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/types/numpy_op_helper.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+ long int_();
+ template <class V>
+ long int_(V v);
+ }
+
+#define NUMPY_NARY_FUNC_NAME int_
+#define NUMPY_NARY_FUNC_SYM details::int_
+#define NUMPY_NARY_EXTRA_METHOD using type = long;
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/intc.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/intc.hpp
new file mode 100644
index 00000000000..0293dc392b6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/intc.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_INTC_HPP
+#define PYTHONIC_INCLUDE_NUMPY_INTC_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/meta.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/types/numpy_op_helper.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ int intc();
+ template <class V>
+ int intc(V v);
+ }
+
+#define NUMPY_NARY_FUNC_NAME intc
+#define NUMPY_NARY_FUNC_SYM details::intc
+#define NUMPY_NARY_EXTRA_METHOD using type = int;
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/interp.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/interp.hpp
new file mode 100644
index 00000000000..320bff15c2c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/interp.hpp
@@ -0,0 +1,100 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_INTERP_HPP
+#define PYTHONIC_INCLUDE_NUMPY_INTERP_HPP
+
+#include "pythonic/include/builtins/None.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_conversion.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ template <class T>
+ using interp_out_type =
+ typename std::conditional<types::is_complex<typename T::dtype>::value,
+ std::complex<double>, double>::type;
+
+ // None,None,None
+ template <class T1, class T2, class T3>
+ typename std::enable_if<
+ !std::is_arithmetic<T1>::value,
+ types::ndarray<interp_out_type<T3>, types::pshape<long>>>::type
+ interp(T1 x, T2 xp, T3 fp, types::none_type left = types::none_type{},
+ types::none_type right = types::none_type{},
+ types::none_type period = types::none_type{});
+
+ // left None None
+ template <class T1, class T2, class T3, typename t1>
+ typename std::enable_if<
+ !std::is_arithmetic<T1>::value,
+ types::ndarray<interp_out_type<T3>, types::pshape<long>>>::type
+ interp(T1 x, T2 xp, T3 fp, t1 left,
+ types::none_type right = types::none_type{},
+ types::none_type period = types::none_type{});
+
+ // None right None
+ template <class T1, class T2, class T3, typename t1>
+ typename std::enable_if<
+ !std::is_arithmetic<T1>::value,
+ types::ndarray<interp_out_type<T3>, types::pshape<long>>>::type
+ interp(T1 x, T2 xp, T3 fp, types::none_type left, t1 right,
+ types::none_type period = types::none_type{});
+ // None None period
+ template <class T1, class T2, class T3, typename t1>
+ typename std::enable_if<
+ !std::is_arithmetic<T1>::value,
+ types::ndarray<interp_out_type<T3>, types::pshape<long>>>::type
+ interp(T1 x, T2 xp, T3 fp, types::none_type left, types::none_type right,
+ t1 period);
+
+ // left right None
+ template <class T1, class T2, class T3, typename t1, typename t2>
+ typename std::enable_if<
+ !std::is_arithmetic<T1>::value,
+ types::ndarray<interp_out_type<T3>, types::pshape<long>>>::type
+ interp(T1 x, T2 xp, T3 fp, t1 left, t2 right,
+ types::none_type period = types::none_type{});
+
+ ////////////////////////// NUMERIC TYPES for x.
+ template <class T1, class T2, class T3>
+ typename std::enable_if<std::is_arithmetic<T1>::value,
+ interp_out_type<T3>>::type
+ interp(T1 x, T2 xp, T3 fp, types::none_type left = types::none_type{},
+ types::none_type right = types::none_type{},
+ types::none_type period = types::none_type{});
+
+ // left None None
+ template <class T1, class T2, class T3, typename t1>
+ typename std::enable_if<std::is_arithmetic<T1>::value,
+ interp_out_type<T3>>::type
+ interp(T1 x, T2 xp, T3 fp, t1 left,
+ types::none_type right = types::none_type{},
+ types::none_type period = types::none_type{});
+
+ // None right None
+ template <class T1, class T2, class T3, typename t1>
+ typename std::enable_if<std::is_arithmetic<T1>::value,
+ interp_out_type<T3>>::type
+ interp(T1 x, T2 xp, T3 fp, types::none_type left, t1 right,
+ types::none_type period = types::none_type{});
+
+ // None None period
+ template <class T1, class T2, class T3, typename t1>
+ typename std::enable_if<std::is_arithmetic<T1>::value,
+ interp_out_type<T3>>::type
+ interp(T1 x, T2 xp, T3 fp, types::none_type left, types::none_type right,
+ t1 period);
+
+ // left right None
+ template <class T1, class T2, class T3, typename t1, typename t2>
+ typename std::enable_if<std::is_arithmetic<T1>::value,
+ interp_out_type<T3>>::type
+ interp(T1 x, T2 xp, T3 fp, t1 left, t2 right,
+ types::none_type period = types::none_type{});
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(interp);
+ DEFINE_FUNCTOR(pythonic::numpy, interp);
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/intersect1d.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/intersect1d.hpp
new file mode 100644
index 00000000000..9888a45a489
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/intersect1d.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_INTERSECT1D_HPP
+#define PYTHONIC_INCLUDE_NUMPY_INTERSECT1D_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/combined.hpp"
+#include "pythonic/include/numpy/asarray.hpp"
+
+#include <algorithm>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E, class F>
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::pshape<long>>
+ intersect1d(E const &e, F const &f);
+
+ DEFINE_FUNCTOR(pythonic::numpy, intersect1d);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/invert.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/invert.hpp
new file mode 100644
index 00000000000..eb1c8bc3fe1
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/invert.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_INVERT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_INVERT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/operator_/invert.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME invert
+#define NUMPY_NARY_FUNC_SYM operator_::invert
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/isclose.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/isclose.hpp
new file mode 100644
index 00000000000..1cdcc438a57
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/isclose.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ISCLOSE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ISCLOSE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/numpy/abs.hpp"
+#include "pythonic/include/numpy/isfinite.hpp"
+#include "pythonic/include/numpy/isnan.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+
+ namespace wrapper
+ {
+ template <class T0, class T1>
+ bool isclose(T0 const &u, T1 const &v, double rtol = 1e-5,
+ double atol = 1e-8, bool equal_nan = false);
+ }
+#define NUMPY_NARY_FUNC_NAME isclose
+#define NUMPY_NARY_FUNC_SYM wrapper::isclose
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/iscomplex.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/iscomplex.hpp
new file mode 100644
index 00000000000..f9fa2ca249f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/iscomplex.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ISCOMPLEX_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ISCOMPLEX_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/types/traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace wrapper
+ {
+ template <class I>
+ typename std::enable_if<types::is_complex<I>::value, bool>::type
+ iscomplex(I const &a);
+
+ template <class I>
+ constexpr typename std::enable_if<!types::is_complex<I>::value, bool>::type
+ iscomplex(I const &a);
+ }
+
+#define NUMPY_NARY_FUNC_NAME iscomplex
+#define NUMPY_NARY_FUNC_SYM wrapper::iscomplex
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/isfinite.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/isfinite.hpp
new file mode 100644
index 00000000000..e0f5e87f70a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/isfinite.hpp
@@ -0,0 +1,32 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ISFINITE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ISFINITE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T>
+ bool isfinite(std::complex<T> const &t)
+ {
+ return std::isfinite(t.real()) && std::isfinite(t.imag());
+ }
+ template <class T>
+ bool isfinite(T const &v)
+ {
+ return std::isfinite(v);
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME isfinite
+#define NUMPY_NARY_FUNC_SYM wrapper::isfinite
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/isinf.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/isinf.hpp
new file mode 100644
index 00000000000..138f6a5cf24
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/isinf.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ISINF_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ISINF_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T>
+ bool isinf(T const &v);
+
+ template <class T>
+ bool isinf(std::complex<T> const &v);
+ }
+#define NUMPY_NARY_FUNC_NAME isinf
+#define NUMPY_NARY_FUNC_SYM wrapper::isinf
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/isnan.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/isnan.hpp
new file mode 100644
index 00000000000..4648d1b01f1
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/isnan.hpp
@@ -0,0 +1,32 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ISNAN_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ISNAN_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T>
+ bool isnan(std::complex<T> const &v);
+ template <class T>
+ auto isnan(T const &v) -> typename std::enable_if<
+ std::is_floating_point<typename std::decay<T>::type>::value,
+ bool>::type;
+ template <class T>
+ auto isnan(T const &v) -> typename std::enable_if<
+ !std::is_floating_point<typename std::decay<T>::type>::value,
+ bool>::type;
+ }
+
+#define NUMPY_NARY_FUNC_NAME isnan
+#define NUMPY_NARY_FUNC_SYM wrapper::isnan
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/isneginf.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/isneginf.hpp
new file mode 100644
index 00000000000..6e0dc821a0b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/isneginf.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ISNEGINF_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ISNEGINF_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include "pythonic/include/numpy/isinf.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T>
+ auto isneginf(T const &t) -> decltype(functor::isinf{}(t) && (t < 0));
+ }
+
+#define NUMPY_NARY_FUNC_NAME isneginf
+#define NUMPY_NARY_FUNC_SYM wrapper::isneginf
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/isposinf.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/isposinf.hpp
new file mode 100644
index 00000000000..a6ee98e41cf
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/isposinf.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ISPOSINF_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ISPOSINF_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/numpy/isinf.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T>
+ auto isposinf(T const &t) -> decltype(functor::isinf{}(t) && t >= 0);
+ }
+#define NUMPY_NARY_FUNC_NAME isposinf
+#define NUMPY_NARY_FUNC_SYM wrapper::isposinf
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/isreal.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/isreal.hpp
new file mode 100644
index 00000000000..f00ee32af2c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/isreal.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ISREAL_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ISREAL_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/types/traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace wrapper
+ {
+ template <class I>
+ typename std::enable_if<types::is_complex<I>::value, bool>::type
+ isreal(I const &a);
+
+ template <class I>
+ typename std::enable_if<!types::is_complex<I>::value, bool>::type
+ isreal(I const &a);
+ }
+
+#define NUMPY_NARY_FUNC_NAME isreal
+#define NUMPY_NARY_FUNC_SYM wrapper::isreal
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/isrealobj.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/isrealobj.hpp
new file mode 100644
index 00000000000..2f131e7b8a1
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/isrealobj.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ISREALOBJ_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ISREALOBJ_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ constexpr bool isrealobj(E const &expr);
+
+ DEFINE_FUNCTOR(pythonic::numpy, isrealobj);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/isscalar.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/isscalar.hpp
new file mode 100644
index 00000000000..a863c041dad
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/isscalar.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ISSCALAR_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ISSCALAR_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/traits.hpp"
+#include "pythonic/include/types/str.hpp"
+
+#include <type_traits>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class E>
+ constexpr bool isscalar(E const &);
+
+ DEFINE_FUNCTOR(pythonic::numpy, isscalar);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/issctype.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/issctype.hpp
new file mode 100644
index 00000000000..bf552fb55ca
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/issctype.hpp
@@ -0,0 +1,30 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ISSCTYPE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ISSCTYPE_HPP
+
+#include "pythonic/include/numpy/isscalar.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace types
+{
+ class str;
+}
+
+namespace numpy
+{
+ template <class E>
+ constexpr auto issctype(E const &expr) ->
+ typename std::enable_if<!types::is_dtype<E>::value &&
+ !std::is_same<E, types::str>::value,
+ bool>::type;
+
+ template <class E>
+ constexpr auto issctype(E const &expr) ->
+ typename std::enable_if<types::is_dtype<E>::value ||
+ std::is_same<E, types::str>::value,
+ bool>::type;
+
+ DEFINE_FUNCTOR(pythonic::numpy, issctype);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ldexp.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ldexp.hpp
new file mode 100644
index 00000000000..7d46b5aff38
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ldexp.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LDEXP_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LDEXP_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME ldexp
+#define NUMPY_NARY_FUNC_SYM std::ldexp
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ldexp/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ldexp/accumulate.hpp
new file mode 100644
index 00000000000..f373499ce2f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ldexp/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LDEXP_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LDEXP_ACCUMULATE_HPP
+
+#define UFUNC_NAME ldexp
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/left_shift.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/left_shift.hpp
new file mode 100644
index 00000000000..7a4cd6decc6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/left_shift.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LEFT_SHIFT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LEFT_SHIFT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/operator_/lshift.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME left_shift
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::lshift
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/left_shift/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/left_shift/accumulate.hpp
new file mode 100644
index 00000000000..7329b19784a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/left_shift/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LEFT_SHIFT_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LEFT_SHIFT_ACCUMULATE_HPP
+
+#define UFUNC_NAME left_shift
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/less.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/less.hpp
new file mode 100644
index 00000000000..d7980a67ded
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/less.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LESS_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LESS_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/operator_/lt.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME less
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::lt
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/less/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/less/accumulate.hpp
new file mode 100644
index 00000000000..947e48d295e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/less/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LESS_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LESS_ACCUMULATE_HPP
+
+#define UFUNC_NAME less
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/less_equal.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/less_equal.hpp
new file mode 100644
index 00000000000..77f792b4c71
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/less_equal.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LESSEQUAL_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LESSEQUAL_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/operator_/le.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME less_equal
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::le
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/less_equal/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/less_equal/accumulate.hpp
new file mode 100644
index 00000000000..185658d3445
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/less_equal/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LESS_EQUAL_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LESS_EQUAL_ACCUMULATE_HPP
+
+#define UFUNC_NAME less_equal
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/lexsort.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/lexsort.hpp
new file mode 100644
index 00000000000..5a6478d8f8e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/lexsort.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LEXSORT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LEXSORT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class pS>
+ types::ndarray<long, types::pshape<long>> lexsort(pS const &keys);
+
+ DEFINE_FUNCTOR(pythonic::numpy, lexsort)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/linalg/matrix_power.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/linalg/matrix_power.hpp
new file mode 100644
index 00000000000..4e00e257363
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/linalg/matrix_power.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LINALG_MATRIX_POWER_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LINALG_MATRIX_POWER_HPP
+
+#include "pythonic/include/numpy/array.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace linalg
+ {
+ template <class E>
+ auto matrix_power(E const &expr, long n)
+ -> decltype(numpy::functor::array{}(expr));
+
+ DEFINE_FUNCTOR(pythonic::numpy::linalg, matrix_power);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/linspace.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/linspace.hpp
new file mode 100644
index 00000000000..090649d85a7
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/linspace.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LINSPACE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LINSPACE_HPP
+
+#include "pythonic/include/numpy/arange.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class dtype = types::dtype_t<double>>
+ types::ndarray<typename dtype::type, types::pshape<long>>
+ linspace(double start, double stop, long num = 50, bool endpoint = true,
+ bool retstep = false, dtype d = dtype());
+
+ DEFINE_FUNCTOR(pythonic::numpy, linspace);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/log10.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/log10.hpp
new file mode 100644
index 00000000000..53edf98c8e0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/log10.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LOG10_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LOG10_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME log10
+#define NUMPY_NARY_FUNC_SYM xsimd::log10
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/log1p.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/log1p.hpp
new file mode 100644
index 00000000000..d294932cba9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/log1p.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LOG1P_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LOG1P_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME log1p
+#define NUMPY_NARY_FUNC_SYM xsimd::log1p
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/log2.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/log2.hpp
new file mode 100644
index 00000000000..b30b3c7ad4e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/log2.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LOG2_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LOG2_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME log2
+#define NUMPY_NARY_FUNC_SYM xsimd::log2
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/logaddexp.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/logaddexp.hpp
new file mode 100644
index 00000000000..9403527921d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/logaddexp.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LOGADDEXP_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LOGADDEXP_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include "pythonic/include/numpy/log.hpp"
+#include "pythonic/include/numpy/exp.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T0, class T1>
+ auto logaddexp(T0 const &t0, T1 const &t1)
+ -> decltype(functor::log{}(functor::exp{}(t0) + functor::exp{}(t1)));
+ }
+
+#define NUMPY_NARY_FUNC_NAME logaddexp
+#define NUMPY_NARY_FUNC_SYM wrapper::logaddexp
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/logaddexp/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/logaddexp/accumulate.hpp
new file mode 100644
index 00000000000..16679c8910a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/logaddexp/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LOGADDEXP_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LOGADDEXP_ACCUMULATE_HPP
+
+#define UFUNC_NAME logaddexp
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/logaddexp2.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/logaddexp2.hpp
new file mode 100644
index 00000000000..b3dbcacd79a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/logaddexp2.hpp
@@ -0,0 +1,30 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LOGADDEXP2_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LOGADDEXP2_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include "pythonic/include/numpy/log2.hpp"
+#include "pythonic/include/numpy/power.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T0, class T1>
+ auto logaddexp2(T0 const &t0, T1 const &t1)
+ -> decltype(functor::log2{}(functor::power{}(T0(2), t0) +
+ functor::power{}(T1(2), t1)));
+ }
+
+#define NUMPY_NARY_FUNC_NAME logaddexp2
+#define NUMPY_NARY_FUNC_SYM wrapper::logaddexp2
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/logaddexp2/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/logaddexp2/accumulate.hpp
new file mode 100644
index 00000000000..bf948c80c97
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/logaddexp2/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LOGADDEXP2_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LOGADDEXP2_ACCUMULATE_HPP
+
+#define UFUNC_NAME logaddexp2
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/logical_and.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/logical_and.hpp
new file mode 100644
index 00000000000..bad0cefd0a4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/logical_and.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LOGICALAND_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LOGICALAND_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace wrapper
+ {
+ template <class T0, class T1>
+ auto logical_and(T0 const &t0, T1 const &t1) -> decltype(t0 &&t1);
+ }
+
+#define NUMPY_NARY_FUNC_NAME logical_and
+#define NUMPY_NARY_FUNC_SYM wrapper::logical_and
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/logical_and/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/logical_and/accumulate.hpp
new file mode 100644
index 00000000000..70353063ed9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/logical_and/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LOGICAL_AND_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LOGICAL_AND_ACCUMULATE_HPP
+
+#define UFUNC_NAME logical_and
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/logical_not.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/logical_not.hpp
new file mode 100644
index 00000000000..3307bb858b1
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/logical_not.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LOGICALNOT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LOGICALNOT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/operator_/not_.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME logical_not
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::not_
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/logical_or.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/logical_or.hpp
new file mode 100644
index 00000000000..5a91098fe95
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/logical_or.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LOGICALOR_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LOGICALOR_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T0, class T1>
+ auto logical_or(T0 const &t0, T1 const &t1) -> decltype(t0 || t1);
+ }
+
+#define NUMPY_NARY_FUNC_NAME logical_or
+#define NUMPY_NARY_FUNC_SYM wrapper::logical_or
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/logical_or/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/logical_or/accumulate.hpp
new file mode 100644
index 00000000000..d905c5e5a79
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/logical_or/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LOGICAL_OR_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LOGICAL_OR_ACCUMULATE_HPP
+
+#define UFUNC_NAME logical_or
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/logical_xor.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/logical_xor.hpp
new file mode 100644
index 00000000000..f7ad2abf81f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/logical_xor.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LOGICALXOR_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LOGICALXOR_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T0, class T1>
+ auto logical_xor(T0 const &t0, T1 const &t1)
+ -> decltype((t0 && !t1) || (t1 && !t0));
+ template <class T0, class T1>
+ bool logical_xor(std::complex<T0> const &t0, std::complex<T1> const &t1)
+ {
+ return (!!t0 && !t1) || (!!t1 && !t0);
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME logical_xor
+#define NUMPY_NARY_FUNC_SYM wrapper::logical_xor
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/logical_xor/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/logical_xor/accumulate.hpp
new file mode 100644
index 00000000000..7baa826829b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/logical_xor/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LOGICAL_XOR_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LOGICAL_XOR_ACCUMULATE_HPP
+
+#define UFUNC_NAME logical_xor
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/logspace.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/logspace.hpp
new file mode 100644
index 00000000000..cc7b5c5963a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/logspace.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LOGSPACE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LOGSPACE_HPP
+
+#include "pythonic/include/numpy/linspace.hpp"
+#include "pythonic/include/numpy/power.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ auto logspace(double start, double stop, long num = 50, bool endpoint = true,
+ double base = 10.0)
+ -> decltype(functor::power()(base, functor::linspace()(start, stop, num,
+ endpoint)));
+
+ DEFINE_FUNCTOR(pythonic::numpy, logspace);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/longlong.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/longlong.hpp
new file mode 100644
index 00000000000..cde5bf455f3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/longlong.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_LONGLONG_HPP
+#define PYTHONIC_INCLUDE_NUMPY_LONGLONG_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/meta.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/types/numpy_op_helper.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ long long longlong();
+ template <class V>
+ long long longlong(V v);
+ }
+
+#define NUMPY_NARY_FUNC_NAME longlong
+#define NUMPY_NARY_FUNC_SYM details::longlong
+#define NUMPY_NARY_EXTRA_METHOD using type = long long;
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/maximum/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/maximum/accumulate.hpp
new file mode 100644
index 00000000000..cbcf3d2c9f4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/maximum/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_MAXIMUM_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_MAXIMUM_ACCUMULATE_HPP
+
+#define UFUNC_NAME maximum
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/maximum/reduce.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/maximum/reduce.hpp
new file mode 100644
index 00000000000..c508ddf0114
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/maximum/reduce.hpp
@@ -0,0 +1,10 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_MAXIMUM_REDUCE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_MAXIMUM_REDUCE_HPP
+
+#define UFUNC_NAME maximum
+#define UFUNC_INAME imax
+#include "pythonic/include/numpy/ufunc_reduce.hpp"
+#undef UFUNC_NAME
+#undef UFUNC_INAME
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/mean.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/mean.hpp
new file mode 100644
index 00000000000..9028bc0e731
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/mean.hpp
@@ -0,0 +1,64 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_MEAN_HPP
+#define PYTHONIC_INCLUDE_NUMPY_MEAN_HPP
+
+#include "pythonic/include/numpy/sum.hpp"
+#include "pythonic/include/numpy/expand_dims.hpp"
+#include "pythonic/include/builtins/None.hpp"
+#include "pythonic/include/types/immediate.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace details
+ {
+ template <size_t N>
+ struct make_scalar_pshape
+ : sutils::concat<types::pshape<std::integral_constant<long, 1>>,
+ typename make_scalar_pshape<N - 1>::type> {
+ };
+
+ template <>
+ struct make_scalar_pshape<1> {
+ using type = types::pshape<std::integral_constant<long, 1>>;
+ };
+
+ template <class dtype>
+ struct dtype_or_double_helper {
+ using type = typename dtype::type;
+ };
+ template <>
+ struct dtype_or_double_helper<types::none_type> {
+ using type = double;
+ };
+ template <class dtype>
+ using dtype_or_double = typename dtype_or_double_helper<dtype>::type;
+ }
+
+ template <class E, class dtype = types::none_type>
+ auto mean(E const &expr, types::none_type axis = {}, dtype d = {},
+ types::none_type out = {}, types::false_immediate keep_dims = {})
+ -> decltype(sum(expr, axis, d) /
+ details::dtype_or_double<dtype>(expr.flat_size()));
+
+ template <class E, class dtype = types::none_type>
+ auto mean(E const &expr, long axis, dtype d = {}, types::none_type out = {},
+ types::false_immediate keep_dims = {})
+ -> decltype(sum(expr, axis, d));
+
+ template <class E, class dtype>
+ types::ndarray<details::dtype_or_double<dtype>,
+ typename details::make_scalar_pshape<E::value>::type>
+ mean(E const &expr, types::none_type axis, dtype d, types::none_type out,
+ types::true_immediate keep_dims);
+
+ template <class E, class dtype>
+ auto mean(E const &expr, long axis, dtype d, types::none_type out,
+ types::true_immediate keep_dims)
+ -> decltype(expand_dims(mean(expr, axis, d), axis));
+
+ DEFINE_FUNCTOR(pythonic::numpy, mean);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/minimum/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/minimum/accumulate.hpp
new file mode 100644
index 00000000000..3aa3a6f167d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/minimum/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_MINIMUM_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_MINIMUM_ACCUMULATE_HPP
+
+#define UFUNC_NAME minimum
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/minimum/reduce.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/minimum/reduce.hpp
new file mode 100644
index 00000000000..29a2fb113f8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/minimum/reduce.hpp
@@ -0,0 +1,10 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_MINIMUM_REDUCE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_MINIMUM_REDUCE_HPP
+
+#define UFUNC_NAME minimum
+#define UFUNC_INAME imin
+#include "pythonic/include/numpy/ufunc_reduce.hpp"
+#undef UFUNC_NAME
+#undef UFUNC_INAME
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/mod/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/mod/accumulate.hpp
new file mode 100644
index 00000000000..3bd544ddbcd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/mod/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_MOD_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_MOD_ACCUMULATE_HPP
+
+#define UFUNC_NAME mod
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/multiply.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/multiply.hpp
new file mode 100644
index 00000000000..dd0803a20e9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/multiply.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_MULTIPLY_HPP
+#define PYTHONIC_INCLUDE_NUMPY_MULTIPLY_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/operator_/mul.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME multiply
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::mul
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/multiply/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/multiply/accumulate.hpp
new file mode 100644
index 00000000000..85c71344473
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/multiply/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_MULTIPLY_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_MULTIPLY_ACCUMULATE_HPP
+
+#define UFUNC_NAME multiply
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/multiply/reduce.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/multiply/reduce.hpp
new file mode 100644
index 00000000000..61644643064
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/multiply/reduce.hpp
@@ -0,0 +1,10 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_MULTIPLY_REDUCE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_MULTIPLY_REDUCE_HPP
+
+#define UFUNC_NAME multiply
+#define UFUNC_INAME imul
+#include "pythonic/include/numpy/ufunc_reduce.hpp"
+#undef UFUNC_NAME
+#undef UFUNC_INAME
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/nan.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/nan.hpp
new file mode 100644
index 00000000000..cb28e8bed58
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/nan.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NAN_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NAN_HPP
+
+#include <limits>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ double const nan = std::numeric_limits<double>::quiet_NaN();
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/nan_to_num.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/nan_to_num.hpp
new file mode 100644
index 00000000000..fd14db8bd23
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/nan_to_num.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NANTONUM_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NANTONUM_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/numpy/isnan.hpp"
+
+#include <limits>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace wrapper
+ {
+ template <class I>
+ I nan_to_num(I const &a);
+ }
+
+#define NUMPY_NARY_FUNC_NAME nan_to_num
+#define NUMPY_NARY_FUNC_SYM wrapper::nan_to_num
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/nanargmax.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/nanargmax.hpp
new file mode 100644
index 00000000000..8815b77847d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/nanargmax.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NANARGMAX_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NANARGMAX_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/numpy/isnan.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ long nanargmax(E const &expr);
+
+ DEFINE_FUNCTOR(pythonic::numpy, nanargmax);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/nanargmin.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/nanargmin.hpp
new file mode 100644
index 00000000000..dba681ce9b4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/nanargmin.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NANARGMIN_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NANARGMIN_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ long nanargmin(E const &expr);
+
+ DEFINE_FUNCTOR(pythonic::numpy, nanargmin);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/nanmax.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/nanmax.hpp
new file mode 100644
index 00000000000..542f6b03282
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/nanmax.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NANMAX_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NANMAX_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/numpy/isnan.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ typename E::dtype nanmax(E const &expr);
+
+ DEFINE_FUNCTOR(pythonic::numpy, nanmax);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/nanmin.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/nanmin.hpp
new file mode 100644
index 00000000000..82853a94b84
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/nanmin.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NANMIN_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NANMIN_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/numpy/isnan.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ typename E::dtype nanmin(E const &expr);
+
+ DEFINE_FUNCTOR(pythonic::numpy, nanmin);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/nansum.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/nansum.hpp
new file mode 100644
index 00000000000..b47f54fa9cc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/nansum.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NANSUM_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NANSUM_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E, class F>
+ void _nansum(E begin, E end, F &sum, utils::int_<1>);
+
+ template <class E, class F, size_t N>
+ void _nansum(E begin, E end, F &sum, utils::int_<N>);
+
+ template <class E>
+ typename E::dtype nansum(E const &expr);
+
+ DEFINE_FUNCTOR(pythonic::numpy, nansum);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray.hpp
new file mode 100644
index 00000000000..655f0b1f13e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray.hpp
@@ -0,0 +1,30 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NDARRAY_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NDARRAY_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/nested_container.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class pS, class dtype = functor::float64>
+ types::ndarray<typename dtype::type, sutils::shape_t<pS>>
+ ndarray(pS const &shape, dtype d = dtype());
+
+ template <class dtype = functor::float64>
+ types::ndarray<typename dtype::type, types::pshape<long>>
+ ndarray(long size, dtype d = dtype());
+
+ template <long N, class dtype = functor::float64>
+ types::ndarray<typename dtype::type,
+ types::pshape<std::integral_constant<long, N>>>
+ ndarray(std::integral_constant<long, N>, dtype d = dtype());
+
+ DEFINE_FUNCTOR(pythonic::numpy, ndarray);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/astype.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/astype.hpp
new file mode 100644
index 00000000000..2cdde10c734
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/astype.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NDARRAY_ASTYPE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NDARRAY_ASTYPE_HPP
+
+#include "pythonic/include/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace ndarray
+ {
+
+ template <class E, class dtype>
+ auto astype(E &&e, dtype d) -> decltype(asarray(std::forward<E>(e), d));
+
+ DEFINE_FUNCTOR(pythonic::numpy::ndarray, astype);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/flatten.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/flatten.hpp
new file mode 100644
index 00000000000..c2007186895
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/flatten.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NDARRAY_FLATTEN_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NDARRAY_FLATTEN_HPP
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace ndarray
+ {
+ template <class T, class pS>
+ types::ndarray<T, types::pshape<long>>
+ flatten(types::ndarray<T, pS> const &a);
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(flatten);
+ DEFINE_FUNCTOR(pythonic::numpy::ndarray, flatten);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/item.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/item.hpp
new file mode 100644
index 00000000000..aed8c4928db
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/item.hpp
@@ -0,0 +1,30 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NDARRAY_ITEM_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NDARRAY_ITEM_HPP
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace ndarray
+ {
+
+ template <class T, class pS>
+ T item(types::ndarray<T, pS> const &expr, long i);
+
+ template <class E, size_t N>
+ auto item(E &&expr, types::array<long, N> const &i) -> decltype(expr[i]);
+
+ // only for compatibility purpose, very bad impl
+ template <class E>
+ typename std::decay<E>::type::dtype item(E &&expr, long i);
+
+ DEFINE_FUNCTOR(pythonic::numpy::ndarray, item);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/reshape.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/reshape.hpp
new file mode 100644
index 00000000000..b1f8359ffc7
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/reshape.hpp
@@ -0,0 +1,36 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NDARRAY_RESHAPE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NDARRAY_RESHAPE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_conversion.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace ndarray
+ {
+ template <class T, class pS, class NpS>
+ typename std::enable_if<!std::is_integral<NpS>::value,
+ types::ndarray<T, NpS>>::type
+ reshape(types::ndarray<T, pS> const &expr, NpS const &new_shape);
+ template <class T, class pS, class NpS>
+ typename std::enable_if<std::is_integral<NpS>::value,
+ types::ndarray<T, types::pshape<long>>>::type
+ reshape(types::ndarray<T, pS> const &expr, NpS const &new_shape);
+
+ template <class T, class pS, class S0, class S1, class... S>
+ auto reshape(types::ndarray<T, pS> const &expr, S0 i0, S1 i1,
+ S const &... indices)
+ -> decltype(reshape(expr,
+ types::pshape<S0, S1, S...>{i0, i1, indices...}));
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(reshape);
+
+ DEFINE_FUNCTOR(pythonic::numpy::ndarray, reshape);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/tofile.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/tofile.hpp
new file mode 100644
index 00000000000..8e379c504ea
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/tofile.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NDARRAY_TOFILE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NDARRAY_TOFILE_HPP
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_conversion.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/str.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace ndarray
+ {
+ template <class T, class pS>
+ void tofile(types::ndarray<T, pS> const &expr, types::str const &file_name,
+ types::str const &sep = "", types::str const &format = "");
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(tofile);
+ DEFINE_FUNCTOR(pythonic::numpy::ndarray, tofile);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/tolist.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/tolist.hpp
new file mode 100644
index 00000000000..05b82e79193
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/tolist.hpp
@@ -0,0 +1,42 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NDARRAY_TOLIST_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NDARRAY_TOLIST_HPP
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_conversion.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace ndarray
+ {
+ template <class T, size_t N>
+ struct tolist_type {
+ using type = types::list<typename tolist_type<T, N - 1>::type>;
+ };
+
+ template <class T>
+ struct tolist_type<T, 1> {
+ using type = types::list<T>;
+ };
+
+ template <class T, class pS>
+ typename std::enable_if<std::tuple_size<pS>::value == 1,
+ types::list<T>>::type
+ tolist(types::ndarray<T, pS> const &expr);
+
+ template <class T, class pS>
+ typename std::enable_if<
+ std::tuple_size<pS>::value != 1,
+ typename tolist_type<T, std::tuple_size<pS>::value>::type>::type
+ tolist(types::ndarray<T, pS> const &expr);
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(tolist);
+ DEFINE_FUNCTOR(pythonic::numpy::ndarray, tolist);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/tostring.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/tostring.hpp
new file mode 100644
index 00000000000..302b74012be
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/tostring.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NDARRAY_TOSTRING_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NDARRAY_TOSTRING_HPP
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_conversion.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/str.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace ndarray
+ {
+ template <class T, class pS>
+ types::str tostring(types::ndarray<T, pS> const &expr);
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(tostring);
+ DEFINE_FUNCTOR(pythonic::numpy::ndarray, tostring);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/view.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/view.hpp
new file mode 100644
index 00000000000..f2550dc5d43
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ndarray/view.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NDARRAY_VIEW_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NDARRAY_VIEW_HPP
+
+#include "pythonic/include/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace ndarray
+ {
+
+ template <class E>
+ auto view(E &&e) -> decltype(std::forward<E>(e));
+
+ template <class E, class dtype>
+ auto view(E &&e, dtype d)
+ -> decltype(std::forward<E>(e).template recast<typename dtype::type>());
+
+ DEFINE_FUNCTOR(pythonic::numpy::ndarray, view);
+ } // namespace ndarray
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ndenumerate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ndenumerate.hpp
new file mode 100644
index 00000000000..74fb322f5bb
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ndenumerate.hpp
@@ -0,0 +1,54 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NDENUMERATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NDENUMERATE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ struct ndenumerate_iterator
+ : std::iterator<
+ std::random_access_iterator_tag,
+ std::tuple<types::array<long, E::value>, typename E::dtype>> {
+ long index;
+ E const &expr;
+ typename E::dtype *iter;
+
+ ndenumerate_iterator();
+ ndenumerate_iterator(E const &expr, long first);
+
+ std::tuple<types::array<long, E::value>, typename E::dtype>
+ operator*() const;
+
+ ndenumerate_iterator &operator++();
+ ndenumerate_iterator &operator+=(long n);
+ bool operator!=(ndenumerate_iterator const &other) const;
+ bool operator<(ndenumerate_iterator const &other) const;
+ long operator-(ndenumerate_iterator const &other) const;
+ };
+
+ template <class E>
+ struct _ndenumerate : ndenumerate_iterator<E> {
+ using iterator = ndenumerate_iterator<E>;
+ E expr; // we need to keep one ref over the enumerated sequence alive
+ iterator end_iter;
+
+ _ndenumerate();
+ _ndenumerate(E const &expr);
+ iterator &begin();
+ iterator const &begin() const;
+ iterator end() const;
+ };
+
+ template <class T, class pS>
+ _ndenumerate<types::ndarray<T, pS>>
+ ndenumerate(types::ndarray<T, pS> const &expr);
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(ndenumerate);
+ DEFINE_FUNCTOR(pythonic::numpy, ndenumerate);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ndim.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ndim.hpp
new file mode 100644
index 00000000000..18aaf4cf176
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ndim.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NDIM_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NDIM_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/numpy/shape.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class E>
+ long ndim(E const &e);
+
+ DEFINE_FUNCTOR(pythonic::numpy, ndim)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ndindex.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ndindex.hpp
new file mode 100644
index 00000000000..ccc4dab5cf6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ndindex.hpp
@@ -0,0 +1,58 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NDINDEX_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NDINDEX_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/tuple.hpp"
+
+#include <numeric>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <size_t N>
+ struct ndindex_iterator
+ : std::iterator<
+ std::random_access_iterator_tag, types::array<long, N>, ptrdiff_t,
+ types::array<long, N> *,
+ types::array<long,
+ N> /* reference_type, but no reference is possible*/> {
+ long index;
+ types::array<long, N> shape;
+ ndindex_iterator();
+ ndindex_iterator(types::array<long, N> const &shape, long first);
+ types::array<long, N> operator*() const;
+ ndindex_iterator &operator++();
+ ndindex_iterator &operator+=(long n);
+ bool operator!=(ndindex_iterator const &other) const;
+ bool operator<(ndindex_iterator const &other) const;
+ long operator-(ndindex_iterator const &other) const;
+ };
+
+ template <size_t N>
+ struct _ndindex : ndindex_iterator<N> {
+ using iterator = ndindex_iterator<N>;
+ types::array<long, N> shape;
+ iterator end_iter;
+
+ _ndindex();
+ _ndindex(types::array<long, N> const &shape);
+ iterator &begin();
+ iterator const &begin() const;
+ iterator end() const;
+ };
+
+ template <class... Types>
+ _ndindex<sizeof...(Types)> ndindex(Types... args);
+
+ template <size_t N>
+ _ndindex<N> ndindex(types::array<long, N> const &args);
+
+ template <class... Tys>
+ _ndindex<sizeof...(Tys)> ndindex(types::pshape<Tys...> const &args);
+
+ DEFINE_FUNCTOR(pythonic::numpy, ndindex);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/negative.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/negative.hpp
new file mode 100644
index 00000000000..26e1f9809ac
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/negative.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NEGATIVE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NEGATIVE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/operator_/neg.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME negative
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::neg
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/negative/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/negative/accumulate.hpp
new file mode 100644
index 00000000000..eb55292aa1f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/negative/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NEGATIVE_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NEGATIVE_ACCUMULATE_HPP
+
+#define UFUNC_NAME negative
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/newaxis.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/newaxis.hpp
new file mode 100644
index 00000000000..f1312ce072d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/newaxis.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NEWAXIS_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NEWAXIS_HPP
+
+#include "pythonic/include/types/NoneType.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ auto const &newaxis = builtins::None;
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/nextafter.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/nextafter.hpp
new file mode 100644
index 00000000000..4ecf25f5a5d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/nextafter.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NEXTAFTER_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NEXTAFTER_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME nextafter
+#define NUMPY_NARY_FUNC_SYM std::nextafter
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/nextafter/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/nextafter/accumulate.hpp
new file mode 100644
index 00000000000..fccb6d4e910
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/nextafter/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NEXTAFTER_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NEXTAFTER_ACCUMULATE_HPP
+
+#define UFUNC_NAME nextafter
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/not_equal.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/not_equal.hpp
new file mode 100644
index 00000000000..8c7fc9a007e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/not_equal.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NOTEQUAL_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NOTEQUAL_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/operator_/ne.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME not_equal
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::ne
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/not_equal/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/not_equal/accumulate.hpp
new file mode 100644
index 00000000000..d6d1b010351
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/not_equal/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_NOT_EQUAL_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_NOT_EQUAL_ACCUMULATE_HPP
+
+#define UFUNC_NAME not_equal
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ones_like.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ones_like.hpp
new file mode 100644
index 00000000000..7212aeeeaa7
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ones_like.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ONESLIKE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ONESLIKE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/numpy/ones.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class E, class dtype>
+ auto ones_like(E const &expr, dtype d = dtype())
+ -> decltype(ones(sutils::getshape(expr), d));
+
+ template <class E>
+ auto ones_like(E const &expr, types::none_type d = builtins::None)
+ -> decltype(ones(sutils::getshape(expr),
+ types::dtype_t<typename E::dtype>()));
+
+ DEFINE_FUNCTOR(pythonic::numpy, ones_like)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/outer.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/outer.hpp
new file mode 100644
index 00000000000..bd25e14b1ad
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/outer.hpp
@@ -0,0 +1,34 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_OUTER_HPP
+#define PYTHONIC_INCLUDE_NUMPY_OUTER_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/builtins/None.hpp"
+#include "pythonic/include/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T0, class pS0, class T1, class pS1>
+ types::ndarray<decltype(std::declval<T0>() + std::declval<T1>()),
+ types::pshape<long, long>>
+ outer(types::ndarray<T0, pS0> const &a, types::ndarray<T1, pS1> const &b);
+
+ template <class T0, class pS0, class E1>
+ auto outer(types::ndarray<T0, pS0> const &a, E1 const &b)
+ -> decltype(outer(a, asarray(b)));
+
+ template <class E0, class T1, class pS1>
+ auto outer(E0 const &a, types::ndarray<T1, pS1> const &b)
+ -> decltype(outer(asarray(a), b));
+
+ template <class E0, class E1>
+ auto outer(E0 const &a, E1 const &b)
+ -> decltype(outer(asarray(a), asarray(b)));
+
+ DEFINE_FUNCTOR(pythonic::numpy, outer);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/partial_sum.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/partial_sum.hpp
new file mode 100644
index 00000000000..50267ce09d9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/partial_sum.hpp
@@ -0,0 +1,38 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_PARTIAL_SUM_HPP
+#define PYTHONIC_INCLUDE_NUMPY_PARTIAL_SUM_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class Op, class E>
+ using result_dtype = types::dtype_t<decltype(std::declval<Op>()(
+ std::declval<typename std::remove_reference<E>::type::dtype>(),
+ std::declval<typename std::remove_reference<E>::type::dtype>()))>;
+
+ template <class Op, class E, class dtype = result_dtype<Op, E>>
+ types::ndarray<typename dtype::type, types::pshape<long>>
+ partial_sum(E const &expr, dtype d = dtype());
+
+ template <class Op, class E, class dtype = result_dtype<Op, E>>
+ auto partial_sum(E const &expr, long axis, dtype d = dtype()) ->
+ typename std::enable_if<E::value == 1,
+ decltype(partial_sum<Op, E, dtype>(expr))>::type;
+
+ template <class Op, class E, class dtype = result_dtype<Op, E>>
+ using partial_sum_type =
+ types::ndarray<typename dtype::type, types::array<long, E::value>>;
+ template <class Op, class E, class dtype = result_dtype<Op, E>>
+ using partial_sum_type2 =
+ types::ndarray<typename dtype::type, types::array<long, E::value - 1>>;
+
+ template <class Op, class E, class dtype = result_dtype<Op, E>>
+ typename std::enable_if<E::value != 1, partial_sum_type<Op, E, dtype>>::type
+ partial_sum(E const &expr, long axis, dtype d = dtype());
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/pi.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/pi.hpp
new file mode 100644
index 00000000000..297ebf4c224
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/pi.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_PI_HPP
+#define PYTHONIC_INCLUDE_NUMPY_PI_HPP
+
+#include "pythonic/include/math/pi.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ double constexpr pi = math::pi;
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/place.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/place.hpp
new file mode 100644
index 00000000000..c957d4b5b91
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/place.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_PLACE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_PLACE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/builtins/None.hpp"
+#include "pythonic/include/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS, class Tp, class pSp, class F>
+ types::none_type place(types::ndarray<T, pS> &expr,
+ types::ndarray<Tp, pSp> const &mask, F const &values);
+
+ template <class T, class pS, class M, class F>
+ types::none_type place(types::ndarray<T, pS> &expr, M const &mask,
+ F const &values);
+
+ template <class E, class M, class F>
+ types::none_type place(E &, M const &, F const &);
+
+ DEFINE_FUNCTOR(pythonic::numpy, place);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/power/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/power/accumulate.hpp
new file mode 100644
index 00000000000..0a101dc6e0f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/power/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_POWER_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_POWER_ACCUMULATE_HPP
+
+#define UFUNC_NAME power
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/product.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/product.hpp
new file mode 100644
index 00000000000..d0c0eef06d2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/product.hpp
@@ -0,0 +1,13 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_PRODUCT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_PRODUCT_HPP
+
+#include "pythonic/include/numpy/prod.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ USING_FUNCTOR(product, prod);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ptp.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ptp.hpp
new file mode 100644
index 00000000000..31b6d3b3278
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ptp.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_PTP_HPP
+#define PYTHONIC_INCLUDE_NUMPY_PTP_HPP
+
+#include "pythonic/include/numpy/min.hpp"
+#include "pythonic/include/numpy/max.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ auto ptp(E const &expr, long axis)
+ -> decltype(max(expr, axis) - min(expr, axis));
+
+ template <class E>
+ auto ptp(E const &expr) -> decltype(max(expr) - min(expr));
+
+ DEFINE_FUNCTOR(pythonic::numpy, ptp);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/put.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/put.hpp
new file mode 100644
index 00000000000..23f97766ca5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/put.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_PUT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_PUT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_conversion.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class F, class T, class pS, class E>
+ typename std::enable_if<types::is_numexpr_arg<F>::value,
+ types::none_type>::type
+ put(types::ndarray<T, pS> &expr, F const &ind, E const &v);
+
+ template <class T, class pS>
+ types::none_type put(types::ndarray<T, pS> &expr, long int ind, T const &v);
+
+ template <class E, class M, class V>
+ types::none_type put(E &, M const &, V const &);
+
+ DEFINE_FUNCTOR(pythonic::numpy, put);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/putmask.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/putmask.hpp
new file mode 100644
index 00000000000..e66beae154e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/putmask.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_PUTMASK_HPP
+#define PYTHONIC_INCLUDE_NUMPY_PUTMASK_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/numpy/asarray.hpp"
+#include "pythonic/include/builtins/None.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS, class E, class F>
+ types::none_type putmask(types::ndarray<T, pS> &expr, E const &mask,
+ F const &values);
+
+ template <class E, class M, class F>
+ types::none_type putmask(E &, M const &, F const &);
+
+ DEFINE_FUNCTOR(pythonic::numpy, putmask);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/rad2deg.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/rad2deg.hpp
new file mode 100644
index 00000000000..3a8b06880c0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/rad2deg.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RAD2DEG_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RAD2DEG_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/numpy/pi.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T>
+ auto rad2deg(T const &val) -> decltype(val * 180 / pi)
+ {
+ return val * 180 / pi;
+ }
+ }
+#define NUMPY_NARY_FUNC_NAME rad2deg
+#define NUMPY_NARY_FUNC_SYM wrapper::rad2deg
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/radians.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/radians.hpp
new file mode 100644
index 00000000000..7cb7630d41a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/radians.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RADIANS_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RADIANS_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/numpy/deg2rad.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ USING_FUNCTOR(radians, deg2rad);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/binomial.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/binomial.hpp
new file mode 100644
index 00000000000..fde9a6d5c38
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/binomial.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_BINOMIAL_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_BINOMIAL_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/types/numpy_expr.hpp"
+
+#include "pythonic/include/numpy/random/generator.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<long, pS> binomial(double n, double p, pS const &shape);
+
+ auto binomial(double n, double p, long size)
+ -> decltype(binomial(n, p, types::array<long, 1>{{size}}));
+
+ long binomial(double n, double p, types::none_type d = types::none_type());
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, binomial);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/bytes.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/bytes.hpp
new file mode 100644
index 00000000000..5c2122f3054
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/bytes.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_BYTES_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_BYTES_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/str.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ types::str bytes(long length);
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, bytes);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/chisquare.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/chisquare.hpp
new file mode 100644
index 00000000000..7b23a280052
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/chisquare.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_CHISQUARE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_CHISQUARE_HPP
+
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/tuple.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<double, pS> chisquare(double df, pS const &shape);
+
+ auto chisquare(double df, long size)
+ -> decltype(chisquare(df, types::array<long, 1>{{size}}));
+
+ double chisquare(double df, types::none_type size = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, chisquare);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/choice.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/choice.hpp
new file mode 100644
index 00000000000..f105eef0228
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/choice.hpp
@@ -0,0 +1,51 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_CHOICE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_CHOICE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/numpy/random/randint.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/tuple.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS, class P>
+ types::ndarray<long, pS> choice(long max, pS const &shape, bool replace,
+ P const &p);
+
+ template <class P>
+ types::ndarray<long, types::pshape<long>> choice(long max, long size,
+ bool replace, P &&p);
+
+ template <class T>
+ auto choice(long max, T &&size)
+ -> decltype(randint(0, max, std::forward<T>(size)));
+
+ long choice(long max);
+
+ template <class T>
+ typename T::dtype choice(T const &a);
+
+ template <class T, class pS>
+ types::ndarray<typename T::dtype, pS> choice(T const &a, pS const &shape);
+
+ template <class T>
+ types::ndarray<typename T::dtype, types::pshape<long>> choice(T &&a,
+ long size);
+
+ template <class T, class pS, class P>
+ types::ndarray<typename T::dtype, pS> choice(T const &a, pS const &shape,
+ bool replace, P const &p);
+
+ template <class T, class P>
+ types::ndarray<typename T::dtype, types::pshape<long>>
+ choice(T &&a, long size, bool replace, P &&p);
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, choice);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/dirichlet.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/dirichlet.hpp
new file mode 100644
index 00000000000..a4de3ff1629
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/dirichlet.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_DIRICHLET_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_DIRICHLET_HPP
+
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/tuple.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<double, pS> dirichlet(double alpha, pS const &shape);
+
+ auto dirichlet(double alpha, long size)
+ -> decltype(dirichlet(alpha, types::array<long, 1>{{size}}));
+
+ double dirichlet(double alpha, types::none_type size = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, dirichlet);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/exponential.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/exponential.hpp
new file mode 100644
index 00000000000..14b8bd7a5ed
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/exponential.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_EXPONENTIAL_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_EXPONENTIAL_HPP
+
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/tuple.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<double, pS> exponential(double scale, pS const &shape);
+
+ auto exponential(double scale, long size)
+ -> decltype(exponential(scale, types::array<long, 1>{{size}}));
+
+ double exponential(double scale = 1.0, types::none_type size = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, exponential);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/f.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/f.hpp
new file mode 100644
index 00000000000..fca6ba2a063
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/f.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_F_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_F_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/tuple.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<double, pS> f(double dfnum, double dfden, pS const &shape);
+
+ auto f(double dfnum, double dfden, long size)
+ -> decltype(f(dfnum, dfden, types::array<long, 1>{{size}}));
+
+ double f(double dfnum, double dfden, types::none_type size = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, f);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/gamma.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/gamma.hpp
new file mode 100644
index 00000000000..a14ad16e767
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/gamma.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_GAMMA_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_GAMMA_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/tuple.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<double, pS> gamma(double shape, double scale,
+ pS const &array_shape);
+
+ auto gamma(double shape, double scale, long size)
+ -> decltype(gamma(shape, scale, types::array<long, 1>{{size}}));
+
+ double gamma(double shape = 0.0, double scale = 1.0,
+ types::none_type size = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, gamma);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/generator.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/generator.hpp
new file mode 100644
index 00000000000..2c9d7b5b024
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/generator.hpp
@@ -0,0 +1,102 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_GENERATOR_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_GENERATOR_HPP
+
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ namespace details
+ {
+
+ /*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <[email protected]>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ *implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation
+ *scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+ class pcg
+ {
+ uint64_t state;
+ static constexpr uint64_t inc = 0xda3e39cb94b95bdbULL;
+
+ public:
+ using result_type = uint32_t;
+ static constexpr result_type min()
+ {
+ return 0;
+ }
+ static constexpr result_type max()
+ {
+ return std::numeric_limits<uint32_t>::max();
+ }
+ friend bool operator==(pcg const &self, pcg const &other)
+ {
+ return self.state == other.state;
+ }
+ friend bool operator!=(pcg const &self, pcg const &other)
+ {
+ return self.state != other.state;
+ }
+
+ pcg() : state(0)
+ {
+ }
+ explicit pcg(std::random_device &rd)
+ {
+ seed(rd());
+ }
+
+ void seed(uint64_t value = 0)
+ {
+ state = value;
+ (void)operator()();
+ }
+
+ result_type operator()()
+ {
+ uint64_t oldstate = state;
+ state = oldstate * 6364136223846793005ULL + inc;
+ uint32_t xorshifted = uint32_t(((oldstate >> 18u) ^ oldstate) >> 27u);
+ int rot = oldstate >> 59u;
+ return (xorshifted >> rot) | (xorshifted << ((-rot) & 31));
+ }
+
+ void discard(std::size_t n)
+ {
+ for (std::size_t i = 0; i < n; ++i)
+ operator()();
+ }
+
+ private:
+ };
+
+ std::random_device rd;
+ pcg generator(rd);
+ } // namespace details
+ } // namespace random
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/geometric.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/geometric.hpp
new file mode 100644
index 00000000000..a3ab8f83f1b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/geometric.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_GEOMETRIC_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_GEOMETRIC_HPP
+
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/tuple.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<double, pS> geometric(double p, pS const &shape);
+
+ auto geometric(double p, long size)
+ -> decltype(geometric(p, types::array<long, 1>{{size}}));
+
+ double geometric(double, types::none_type size = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, geometric);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/gumbel.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/gumbel.hpp
new file mode 100644
index 00000000000..2f2633aa01c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/gumbel.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_GUMBEL_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_GUMBEL_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/tuple.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<double, pS> gumbel(double loc, double scale,
+ pS const &shape);
+
+ auto gumbel(double loc, double scale, long size)
+ -> decltype(gumbel(loc, scale, types::array<long, 1>{{size}}));
+
+ double gumbel(double loc = 0.0, double scale = 1.0,
+ types::none_type size = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, gumbel);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/laplace.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/laplace.hpp
new file mode 100644
index 00000000000..7e017ab3404
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/laplace.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_LAPLACE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_LAPLACE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/tuple.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<double, pS> laplace(double loc, double scale,
+ pS const &shape);
+
+ auto laplace(double loc, double scale, long size)
+ -> decltype(laplace(loc, scale, types::array<long, 1>{{size}}));
+
+ double laplace(double loc = 0.0, double scale = 1.0,
+ types::none_type size = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, laplace);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/logistic.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/logistic.hpp
new file mode 100644
index 00000000000..c4266581bad
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/logistic.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_LOGISTIC_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_LOGISTIC_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/tuple.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<double, pS> logistic(double loc, double scale,
+ pS const &shape);
+
+ auto logistic(double loc, double scale, long size)
+ -> decltype(logistic(loc, scale, types::array<long, 1>{{size}}));
+
+ double logistic(double loc = 0.0, double scale = 1.0,
+ types::none_type size = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, logistic);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/lognormal.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/lognormal.hpp
new file mode 100644
index 00000000000..a1658a0885e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/lognormal.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_LOGNORMAL_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_LOGNORMAL_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/tuple.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<double, pS> lognormal(double mean, double sigma,
+ pS const &shape);
+
+ auto lognormal(double mean, double sigma, long size)
+ -> decltype(lognormal(mean, sigma, types::array<long, 1>{{size}}));
+
+ double lognormal(double mean = 0.0, double sigma = 1.0,
+ types::none_type size = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, lognormal);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/logseries.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/logseries.hpp
new file mode 100644
index 00000000000..70e013ea7b0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/logseries.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_LOGSERIES_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_LOGSERIES_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/tuple.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<double, pS> logseries(double loc, pS const &shape);
+
+ auto logseries(double loc, long size)
+ -> decltype(logseries(loc, types::array<long, 1>{{size}}));
+
+ double logseries(double loc, types::none_type size = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, logseries);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/negative_binomial.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/negative_binomial.hpp
new file mode 100644
index 00000000000..2ee2f5b4e95
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/negative_binomial.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_NEGATIVE_BINOMIAL_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_NEGATIVE_BINOMIAL_HPP
+
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/tuple.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<long, pS> negative_binomial(long n, double p,
+ pS const &shape);
+
+ auto negative_binomial(long n, double p, long size)
+ -> decltype(negative_binomial(n, p, types::array<long, 1>{{size}}));
+
+ long negative_binomial(long n, double p, types::none_type size = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, negative_binomial);
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/normal.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/normal.hpp
new file mode 100644
index 00000000000..0fa8994800a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/normal.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_NORMAL_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_NORMAL_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/tuple.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<double, pS> normal(double loc, double scale,
+ pS const &shape);
+
+ auto normal(double loc, double scale, long size)
+ -> decltype(normal(loc, scale, types::array<long, 1>{{size}}));
+
+ double normal(double loc = 0.0, double scale = 1.0,
+ types::none_type size = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, normal);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/pareto.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/pareto.hpp
new file mode 100644
index 00000000000..0cc17e1dd74
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/pareto.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_PARETO_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_PARETO_HPP
+
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/tuple.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include <math.h>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<double, pS> pareto(double a, pS const &shape);
+
+ auto pareto(double a, long size)
+ -> decltype(pareto(a, types::array<long, 1>{{size}}));
+
+ double pareto(double a, types::none_type size = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, pareto);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/poisson.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/poisson.hpp
new file mode 100644
index 00000000000..5c55ce22c24
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/poisson.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_POISSON_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_POISSON_HPP
+
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/tuple.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<double, pS> poisson(double lam, pS const &shape);
+
+ auto poisson(double lam, long size)
+ -> decltype(poisson(lam, types::array<long, 1>{{size}}));
+
+ double poisson(double lam = 1.0, types::none_type size = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, poisson);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/power.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/power.hpp
new file mode 100644
index 00000000000..3f9fc63ffca
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/power.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_POWER_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_POWER_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/tuple.hpp"
+#include <math.h>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<double, pS> power(double a, pS const &shape);
+ auto power(double a, long size)
+ -> decltype(power(a, types::array<long, 1>{{size}}));
+
+ double power(double a, types::none_type size = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, power);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/rand.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/rand.hpp
new file mode 100644
index 00000000000..54f14c8ae67
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/rand.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_RAND_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_RAND_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class... T>
+ types::ndarray<double, types::array<long, sizeof...(T)>> rand(T... shape);
+
+ double rand();
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, rand);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/randint.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/randint.hpp
new file mode 100644
index 00000000000..58117b85a5b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/randint.hpp
@@ -0,0 +1,39 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_RANDINT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_RANDINT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/tuple.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ typename std::enable_if<!std::is_integral<pS>::value,
+ types::ndarray<long, pS>>::type
+ randint(long min, long max, pS const &shape);
+
+ template <class pS>
+ typename std::enable_if<std::is_integral<pS>::value,
+ types::ndarray<long, types::pshape<long>>>::type
+ randint(long min, long max, pS const &shape);
+
+ template <class pS>
+ auto randint(long max, types::none_type, pS const &shape)
+ -> decltype(randint(0, max, shape));
+
+ long randint(long min, long max);
+
+ long randint(long max, types::none_type = {});
+
+ auto randint(long min, long max, long size)
+ -> decltype(randint(min, max, types::array<long, 1>{{size}}));
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, randint);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/randn.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/randn.hpp
new file mode 100644
index 00000000000..f33fce310b3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/randn.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_RANDN_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_RANDN_HPP
+
+#include "pythonic/include/numpy/random/generator.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class... T>
+ types::ndarray<double, types::array<long, sizeof...(T)>> randn(T... shape);
+
+ double randn();
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, randn);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/random.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/random.hpp
new file mode 100644
index 00000000000..faaaceaa1f9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/random.hpp
@@ -0,0 +1,33 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_RANDOM_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_RANDOM_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/tuple.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<double, pS> random(pS const &shape);
+
+ auto random(long size) -> decltype(random(types::array<long, 1>{{size}}));
+
+ template <long N>
+ auto random(std::integral_constant<long, N>)
+ -> decltype(random(types::array<std::integral_constant<long, N>, 1>{}))
+ {
+ return random(types::array<std::integral_constant<long, N>, 1>{});
+ }
+
+ double random(types::none_type d = types::none_type());
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, random);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/random_integers.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/random_integers.hpp
new file mode 100644
index 00000000000..a731edab409
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/random_integers.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_RANDOM_INTEGERS_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_RANDOM_INTEGERS_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/numpy/random/randint.hpp"
+
+#include <utility>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class T>
+ auto random_integers(long min, long max, T &&size)
+ -> decltype(randint(min, max, std::forward<T>(size)));
+
+ long random_integers(long max);
+
+ long random_integers(long min, long max);
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, random_integers);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/random_sample.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/random_sample.hpp
new file mode 100644
index 00000000000..bb17bed478c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/random_sample.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_RANDOM_SAMPLE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_RANDOM_SAMPLE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/numpy/random/random.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ USING_FUNCTOR(random_sample, random);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/ranf.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/ranf.hpp
new file mode 100644
index 00000000000..82c1db1f2f6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/ranf.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_RANF_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_RANF_HPP
+
+#include "pythonic/include/numpy/random/random.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ USING_FUNCTOR(ranf, random);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/rayleigh.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/rayleigh.hpp
new file mode 100644
index 00000000000..6f3eb1f3b9f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/rayleigh.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_RAYLEIGH_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_RAYLEIGH_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/tuple.hpp"
+#include <math.h>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<double, pS> rayleigh(double scale, pS const &array_shape);
+
+ auto rayleigh(double scale, long size)
+ -> decltype(rayleigh(scale, types::array<long, 1>{{size}}));
+
+ double rayleigh(double scale = 1.0, types::none_type size = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, rayleigh);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/sample.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/sample.hpp
new file mode 100644
index 00000000000..4ac5a4f2b34
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/sample.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_SAMPLE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_SAMPLE_HPP
+
+#include "pythonic/include/numpy/random/random.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ USING_FUNCTOR(sample, random);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/seed.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/seed.hpp
new file mode 100644
index 00000000000..358462fbc91
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/seed.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_SEED_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_SEED_HPP
+
+#include "pythonic/include/numpy/random/generator.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace random
+ {
+ types::none_type seed(long s);
+ types::none_type seed(types::none_type _ = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, seed);
+ }
+}
+
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/shuffle.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/shuffle.hpp
new file mode 100644
index 00000000000..4245f55c220
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/shuffle.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_SHUFFLE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_SHUFFLE_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/numpy/random/generator.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace random
+ {
+ template <class T>
+ types::none_type shuffle(T &seq);
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, shuffle);
+ }
+}
+
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/standard_exponential.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/standard_exponential.hpp
new file mode 100644
index 00000000000..4ae39edc88d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/standard_exponential.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_STANDARD_EXPONENTIAL_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_STANDARD_EXPONENTIAL_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/tuple.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<double, pS> standard_exponential(pS const &shape);
+
+ auto standard_exponential(long size)
+ -> decltype(standard_exponential(types::array<long, 1>{{size}}));
+
+ double standard_exponential(types::none_type d = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, standard_exponential);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/standard_gamma.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/standard_gamma.hpp
new file mode 100644
index 00000000000..8ca27a14557
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/standard_gamma.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_STANDARD_GAMMA_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_STANDARD_GAMMA_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/tuple.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<double, pS> standard_gamma(double s, pS const &shape);
+
+ auto standard_gamma(double s, long size)
+ -> decltype(standard_gamma(s, types::array<long, 1>{{size}}));
+
+ double standard_gamma(double s, types::none_type d = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, standard_gamma);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/standard_normal.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/standard_normal.hpp
new file mode 100644
index 00000000000..3dd2be0475c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/standard_normal.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_STANDARD_NORMAL_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_STANDARD_NORMAL_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/tuple.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<double, pS> standard_normal(pS const &shape);
+
+ auto standard_normal(long size)
+ -> decltype(standard_normal(types::array<long, 1>{{size}}));
+
+ double standard_normal(types::none_type d = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, standard_normal);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/uniform.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/uniform.hpp
new file mode 100644
index 00000000000..fee7eb84daa
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/uniform.hpp
@@ -0,0 +1,30 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_UNIFORM_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_UNIFORM_HPP
+
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/tuple.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include <math.h>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<double, pS> uniform(double low, double high,
+ pS const &array_shape);
+
+ auto uniform(double low, double high, long size)
+ -> decltype(uniform(low, high, types::array<long, 1>{{size}}));
+
+ double uniform(double low = 0.0, double high = 1.0,
+ types::none_type size = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, uniform);
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/random/weibull.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/random/weibull.hpp
new file mode 100644
index 00000000000..b4411da214d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/random/weibull.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_WEIBULL_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RANDOM_WEIBULL_HPP
+
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/tuple.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class pS>
+ types::ndarray<double, pS> weibull(double a, pS const &shape);
+
+ auto weibull(double a, long size)
+ -> decltype(weibull(a, types::array<long, 1>{{size}}));
+
+ double weibull(double a, types::none_type size = {});
+
+ DEFINE_FUNCTOR(pythonic::numpy::random, weibull);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ravel.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ravel.hpp
new file mode 100644
index 00000000000..797b00edb29
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ravel.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RAVEL_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RAVEL_HPP
+
+#include "pythonic/include/numpy/ndarray/reshape.hpp"
+#include "pythonic/include/utils/numpy_conversion.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS>
+ types::ndarray<T, types::pshape<long>>
+ ravel(types::ndarray<T, pS> const &expr);
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(ravel);
+ DEFINE_FUNCTOR(pythonic::numpy, ravel);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/reciprocal.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/reciprocal.hpp
new file mode 100644
index 00000000000..de6e15078d5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/reciprocal.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RECIPROCAL_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RECIPROCAL_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T>
+ auto reciprocal(T const &val) -> decltype(static_cast<T>(1.) / val)
+ {
+ return static_cast<T>(1.) / val;
+ }
+ }
+#define NUMPY_NARY_FUNC_NAME reciprocal
+#define NUMPY_NARY_FUNC_SYM wrapper::reciprocal
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/remainder.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/remainder.hpp
new file mode 100644
index 00000000000..e2d310d8637
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/remainder.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_REMAINDER_HPP
+#define PYTHONIC_INCLUDE_NUMPY_REMAINDER_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T0, class T1>
+ auto remainder(T0 const &x, T1 const &y)
+ -> decltype(x - y * xsimd::floor(x / y))
+ {
+ return x - y * xsimd::floor(x / y);
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME remainder
+#define NUMPY_NARY_FUNC_SYM wrapper::remainder
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/remainder/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/remainder/accumulate.hpp
new file mode 100644
index 00000000000..18b32833ffc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/remainder/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_REMAINDER_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_REMAINDER_ACCUMULATE_HPP
+
+#define UFUNC_NAME remainder
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/repeat.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/repeat.hpp
new file mode 100644
index 00000000000..e5a37d1ea5b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/repeat.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_REPEAT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_REPEAT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_conversion.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/builtins/None.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ repeat(types::ndarray<T, pS> const &expr, long repeats, long axis);
+
+ template <class T, class pS>
+ types::ndarray<T, types::pshape<long>>
+ repeat(types::ndarray<T, pS> const &expr, long repeats,
+ types::none_type axis = types::none_type{});
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(repeat);
+ DEFINE_FUNCTOR(pythonic::numpy, repeat);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/resize.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/resize.hpp
new file mode 100644
index 00000000000..4ea024f99b6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/resize.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RESIZE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RESIZE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/numpy/ndarray/reshape.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ USING_FUNCTOR(resize, pythonic::numpy::ndarray::functor::reshape);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/right_shift.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/right_shift.hpp
new file mode 100644
index 00000000000..e6f93acc2fa
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/right_shift.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RIGHTSHIFT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RIGHTSHIFT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include "pythonic/include/operator_/rshift.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME right_shift
+#define NUMPY_NARY_FUNC_SYM operator_::rshift
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/right_shift/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/right_shift/accumulate.hpp
new file mode 100644
index 00000000000..c50779b3ec3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/right_shift/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RIGHT_SHIFT_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RIGHT_SHIFT_ACCUMULATE_HPP
+
+#define UFUNC_NAME right_shift
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/rint.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/rint.hpp
new file mode 100644
index 00000000000..49f8694ed55
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/rint.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_RINT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_RINT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T>
+ T rint(T const &v);
+ template <class T>
+ std::complex<T> rint(std::complex<T> const &v);
+ }
+#define NUMPY_NARY_FUNC_NAME rint
+#define NUMPY_NARY_FUNC_SYM wrapper::rint
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/rollaxis.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/rollaxis.hpp
new file mode 100644
index 00000000000..b26633f387e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/rollaxis.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ROLLAXIS_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ROLLAXIS_HPP
+
+#include "pythonic/include/numpy/transpose.hpp"
+#include "pythonic/include/numpy/copy.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ rollaxis(types::ndarray<T, pS> const &a, long axis, long start = 0);
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(rollaxis);
+ DEFINE_FUNCTOR(pythonic::numpy, rollaxis);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/rot90.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/rot90.hpp
new file mode 100644
index 00000000000..1faa224a5d3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/rot90.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ROT90_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ROT90_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_conversion.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/numpy/copy.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ rot90(types::ndarray<T, pS> const &expr, int k = 1);
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(rot90)
+ DEFINE_FUNCTOR(pythonic::numpy, rot90);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/round.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/round.hpp
new file mode 100644
index 00000000000..5b76063515b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/round.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ROUND_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ROUND_HPP
+
+#include "pythonic/include/numpy/around.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ USING_FUNCTOR(round, around);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/round_.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/round_.hpp
new file mode 100644
index 00000000000..8951262f1d8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/round_.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ROUND__HPP
+#define PYTHONIC_INCLUDE_NUMPY_ROUND__HPP
+
+#include "pythonic/include/numpy/around.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ USING_FUNCTOR(round_, around);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/searchsorted.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/searchsorted.hpp
new file mode 100644
index 00000000000..af23a56ef9c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/searchsorted.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_SEARCHSORTED_HPP
+#define PYTHONIC_INCLUDE_NUMPY_SEARCHSORTED_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_conversion.hpp"
+#include "pythonic/include/utils/int_.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/str.hpp"
+
+#include <algorithm>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class T, class U>
+ typename std::enable_if<!types::is_numexpr_arg<T>::value, long>::type
+ searchsorted(U const &a, T const &v, types::str const &side = "left");
+
+ template <class E, class T>
+ typename std::enable_if<
+ types::is_numexpr_arg<E>::value,
+ types::ndarray<long, types::array<long, E::value>>>::type
+ searchsorted(T const &a, E const &v, types::str const &side = "left");
+
+ DEFINE_FUNCTOR(pythonic::numpy, searchsorted);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/select.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/select.hpp
new file mode 100644
index 00000000000..106bf0ad7b2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/select.hpp
@@ -0,0 +1,51 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_SELECT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_SELECT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/int_.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class C, class L>
+ types::ndarray<typename L::dtype, types::array<long, L::value - 1>>
+ select(C const &condlist, L const &choicelist,
+ typename L::dtype _default = 0);
+
+ template <class T, class TpS, class U, class UpS>
+ typename std::enable_if<
+ std::tuple_size<TpS>::value == std::tuple_size<UpS>::value,
+ types::ndarray<T, types::array<long, std::tuple_size<TpS>::value>>>::type
+ select(types::list<types::ndarray<U, UpS>> const &condlist,
+ types::list<types::ndarray<T, TpS>> const &choicelist, T _default = 0);
+
+ template <class T, class TpS, class U, class UpS, size_t M>
+ typename std::enable_if<std::tuple_size<TpS>::value ==
+ std::tuple_size<UpS>::value,
+ types::ndarray<T, TpS>>::type
+ select(types::static_list<types::ndarray<U, UpS>, M> const &condlist,
+ types::static_list<types::ndarray<T, TpS>, M> const &choicelist,
+ T _default = 0);
+
+ template <class T, class TpS, class U, class UpS, size_t M>
+ typename std::enable_if<std::tuple_size<TpS>::value ==
+ std::tuple_size<UpS>::value,
+ types::ndarray<T, TpS>>::type
+ select(types::static_list<types::ndarray<U, UpS>, M> const &condlist,
+ types::list<types::ndarray<T, TpS>> const &choicelist, T _default = 0);
+
+ template <class T, class TpS, class U, class UpS, size_t M>
+ typename std::enable_if<std::tuple_size<TpS>::value ==
+ std::tuple_size<UpS>::value,
+ types::ndarray<T, TpS>>::type
+ select(types::list<types::ndarray<U, UpS>> const &condlist,
+ types::static_list<types::ndarray<T, TpS>, M> const &choicelist,
+ T _default = 0);
+
+ DEFINE_FUNCTOR(pythonic::numpy, select);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/setdiff1d.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/setdiff1d.hpp
new file mode 100644
index 00000000000..84b3fad818b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/setdiff1d.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_SETDIFF1D_HPP
+#define PYTHONIC_INCLUDE_NUMPY_SETDIFF1D_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class T, class U>
+ types::ndarray<typename __combined<typename types::dtype_of<T>::type,
+ typename types::dtype_of<U>::type>::type,
+ types::pshape<long>>
+ setdiff1d(T const &ar1, U const &ar2, bool assume_unique = false);
+
+ DEFINE_FUNCTOR(pythonic::numpy, setdiff1d);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/shape.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/shape.hpp
new file mode 100644
index 00000000000..ebb09f40f7a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/shape.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_SHAPE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_SHAPE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class T, class pS>
+ auto shape(types::ndarray<T, pS> const &e) -> decltype(e._shape);
+
+ template <class E>
+ auto shape(E const &e) -> decltype(sutils::getshape(e));
+
+ DEFINE_FUNCTOR(pythonic::numpy, shape)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/short_.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/short_.hpp
new file mode 100644
index 00000000000..74e74436843
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/short_.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_SHORT__HPP
+#define PYTHONIC_INCLUDE_NUMPY_SHORT__HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/meta.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/types/numpy_op_helper.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ short short_();
+ template <class V>
+ short short_(V v);
+ }
+
+#define NUMPY_NARY_FUNC_NAME short_
+#define NUMPY_NARY_FUNC_SYM details::short_
+#define NUMPY_NARY_EXTRA_METHOD using type = short;
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/sign.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/sign.hpp
new file mode 100644
index 00000000000..b484c496e37
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/sign.hpp
@@ -0,0 +1,36 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_SIGN_HPP
+#define PYTHONIC_INCLUDE_NUMPY_SIGN_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace details
+ {
+#if PyArray_RUNTIME_VERSION < NPY_2_0_API_VERSION
+ template <typename T>
+ std::complex<T> sign(std::complex<T> v)
+ {
+ return xsimd::select(v == 0, v, v / xsimd::abs(v));
+ }
+#endif
+ template <typename T>
+ T sign(T v)
+ {
+ return xsimd::sign(v);
+ }
+
+ } // namespace details
+#define NUMPY_NARY_FUNC_NAME sign
+#define NUMPY_NARY_FUNC_SYM details::sign
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/signbit.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/signbit.hpp
new file mode 100644
index 00000000000..ba75d802b0e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/signbit.hpp
@@ -0,0 +1,30 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_SIGNBIT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_SIGNBIT_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+ template <class T>
+ auto signbit(T val) -> decltype(xsimd::signbit(val) == T(1))
+ {
+ return xsimd::signbit(val) == T(1);
+ }
+ } // namespace details
+
+#define NUMPY_NARY_FUNC_NAME signbit
+#define NUMPY_NARY_FUNC_SYM details::signbit
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/sinh.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/sinh.hpp
new file mode 100644
index 00000000000..b834cdc97d5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/sinh.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_SINH_HPP
+#define PYTHONIC_INCLUDE_NUMPY_SINH_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME sinh
+#define NUMPY_NARY_FUNC_SYM xsimd::sinh
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/size.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/size.hpp
new file mode 100644
index 00000000000..296629748c4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/size.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_SIZE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_SIZE_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class E>
+ auto size(E const &e) -> decltype(e.flat_size());
+
+ inline long size(...)
+ {
+ return 1;
+ }
+
+ DEFINE_FUNCTOR(pythonic::numpy, size)
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/sometrue.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/sometrue.hpp
new file mode 100644
index 00000000000..2f38f43e5fb
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/sometrue.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_SOMETRUE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_SOMETRUE_HPP
+
+#include "pythonic/include/numpy/any.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ USING_FUNCTOR(sometrue, any);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/sort_complex.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/sort_complex.hpp
new file mode 100644
index 00000000000..d0cb3c7d04b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/sort_complex.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_SORTCOMPLEX_HPP
+#define PYTHONIC_INCLUDE_NUMPY_SORTCOMPLEX_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/numpy/sort.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ USING_FUNCTOR(sort_complex, sort)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/spacing.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/spacing.hpp
new file mode 100644
index 00000000000..3f7fe91e55b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/spacing.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_SPACING_HPP
+#define PYTHONIC_INCLUDE_NUMPY_SPACING_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T>
+ auto spacing(T const &v) -> decltype(std::nextafter(v, 1) - v)
+ {
+ return std::nextafter(v, 1) - v;
+ }
+ }
+#define NUMPY_NARY_FUNC_NAME spacing
+#define NUMPY_NARY_FUNC_SYM wrapper::spacing
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/split.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/split.hpp
new file mode 100644
index 00000000000..b6d7ccee27f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/split.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_SPLIT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_SPLIT_HPP
+
+#include "pythonic/include/numpy/array_split.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS>
+ types::list<types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>>
+ split(types::ndarray<T, pS> const &a, long nb_split);
+
+ template <class T, class pS, class I>
+ typename std::enable_if<
+ types::is_iterable<I>::value,
+ types::list<types::ndarray<
+ T, types::array<long, std::tuple_size<pS>::value>>>>::type
+ split(types::ndarray<T, pS> const &a, I const &split_mask);
+
+ template <class E, class I>
+ types::list<types::ndarray<typename E::dtype, types::array<long, E::value>>>
+ split(E const &a, I const &);
+
+ DEFINE_FUNCTOR(pythonic::numpy, split);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/stack.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/stack.hpp
new file mode 100644
index 00000000000..070efe7cce5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/stack.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_STACK_HPP
+#define PYTHONIC_INCLUDE_NUMPY_STACK_HPP
+
+#include <pythonic/include/types/ndarray.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class ArraySequence>
+ types::ndarray<typename ArraySequence::value_type::dtype,
+ types::array<long, ArraySequence::value_type::value + 1>>
+ stack(ArraySequence const &args, long axis = 0);
+
+ namespace details
+ {
+ template <class... Tys>
+ using stack_helper_t =
+ typename __combined<typename assignable<Tys>::type...>::type;
+ }
+
+ template <class... Tys>
+ types::ndarray<typename details::stack_helper_t<Tys...>::dtype,
+ types::array<long, details::stack_helper_t<Tys...>::value + 1>>
+ stack(std::tuple<Tys...> const &args, long axis = 0);
+
+ DEFINE_FUNCTOR(pythonic::numpy, stack);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/std_.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/std_.hpp
new file mode 100644
index 00000000000..101e533bdcf
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/std_.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_STD_HPP
+#define PYTHONIC_INCLUDE_NUMPY_STD_HPP
+
+#include "pythonic/include/numpy/var.hpp"
+#include "pythonic/include/numpy/sqrt.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class... Args>
+ auto std_(Args &&... args)
+ -> decltype(functor::sqrt{}(var(std::forward<Args>(args)...)));
+
+ DEFINE_FUNCTOR(pythonic::numpy, std_);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/subtract.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/subtract.hpp
new file mode 100644
index 00000000000..99e6184aa32
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/subtract.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_SUBTRACT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_SUBTRACT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/operator_/sub.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME subtract
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::sub
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/subtract/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/subtract/accumulate.hpp
new file mode 100644
index 00000000000..8b5085d72e6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/subtract/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_SUBTRACT_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_SUBTRACT_ACCUMULATE_HPP
+
+#define UFUNC_NAME subtract
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/swapaxes.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/swapaxes.hpp
new file mode 100644
index 00000000000..f0dfd4d437b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/swapaxes.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_SWAPAXES_HPP
+#define PYTHONIC_INCLUDE_NUMPY_SWAPAXES_HPP
+
+#include "pythonic/include/numpy/transpose.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T>
+ auto swapaxes(T &&a, int axis1, int axis2) -> decltype(functor::transpose{}(
+ std::forward<T>(a),
+ std::declval<types::array<long, std::decay<T>::type::value>>()));
+
+ DEFINE_FUNCTOR(pythonic::numpy, swapaxes);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/take.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/take.hpp
new file mode 100644
index 00000000000..cd2f7e764fe
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/take.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_TAKE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_TAKE_HPP
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class F, class T>
+ auto take(T &&expr, F &&indices)
+ -> decltype(std::forward<T>(expr)[std::forward<F>(indices)]);
+
+ DEFINE_FUNCTOR(pythonic::numpy, take);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/tan.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/tan.hpp
new file mode 100644
index 00000000000..91d322d8a2d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/tan.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_TAN_HPP
+#define PYTHONIC_INCLUDE_NUMPY_TAN_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME tan
+#define NUMPY_NARY_FUNC_SYM xsimd::tan
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/tanh.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/tanh.hpp
new file mode 100644
index 00000000000..18f38f2d244
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/tanh.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_TANH_HPP
+#define PYTHONIC_INCLUDE_NUMPY_TANH_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME tanh
+#define NUMPY_NARY_FUNC_SYM xsimd::tanh
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/tile.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/tile.hpp
new file mode 100644
index 00000000000..011f00892d1
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/tile.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_TILE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_TILE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ types::ndarray<typename E::dtype, types::array<long, E::value>>
+ tile(E const &expr, long reps);
+
+ template <class E, size_t N>
+ types::ndarray<typename E::dtype, types::array<long, N>>
+ tile(E const &expr, types::array<long, N> const &reps);
+
+ DEFINE_FUNCTOR(pythonic::numpy, tile);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/trace.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/trace.hpp
new file mode 100644
index 00000000000..fbd3282c903
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/trace.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_TRACE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_TRACE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class T>
+ typename T::dtype trace(T const &expr, int offset = 0);
+
+ DEFINE_FUNCTOR(pythonic::numpy, trace)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/tri.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/tri.hpp
new file mode 100644
index 00000000000..bcdd251019e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/tri.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_TRI_HPP
+#define PYTHONIC_INCLUDE_NUMPY_TRI_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/numpy/float64.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class dtype = functor::float64>
+ types::ndarray<typename dtype::type, types::pshape<long, long>>
+ tri(long N, long M = -1, long k = 0, dtype d = dtype());
+
+ DEFINE_FUNCTOR(pythonic::numpy, tri)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/tril.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/tril.hpp
new file mode 100644
index 00000000000..a7a6df584d6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/tril.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_TRIL_HPP
+#define PYTHONIC_INCLUDE_NUMPY_TRIL_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_conversion.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS>
+ types::ndarray<T, pS> tril(types::ndarray<T, pS> const &expr, int k = 0);
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(tril)
+ DEFINE_FUNCTOR(pythonic::numpy, tril)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/trim_zeros.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/trim_zeros.hpp
new file mode 100644
index 00000000000..21489f32bbf
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/trim_zeros.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_TRIMZEROS_HPP
+#define PYTHONIC_INCLUDE_NUMPY_TRIMZEROS_HPP
+
+#include "pythonic/include/types/numpy_gexpr.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T>
+
+ types::numpy_gexpr<T, types::cstride_normalized_slice<1>>
+ trim_zeros(T const &expr, types::str const &trim = "fb");
+
+ DEFINE_FUNCTOR(pythonic::numpy, trim_zeros)
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/triu.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/triu.hpp
new file mode 100644
index 00000000000..a30e68e1273
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/triu.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_TRIU_HPP
+#define PYTHONIC_INCLUDE_NUMPY_TRIU_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_conversion.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS>
+ types::ndarray<T, pS> triu(types::ndarray<T, pS> const &expr, int k = 0);
+
+ NUMPY_EXPR_TO_NDARRAY0_DECL(triu)
+ DEFINE_FUNCTOR(pythonic::numpy, triu)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/true_divide.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/true_divide.hpp
new file mode 100644
index 00000000000..dc7b68a2526
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/true_divide.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_TRUEDIVIDE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_TRUEDIVIDE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/numpy_broadcast.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/operator_/div.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+// FIXME: this is ! always a true_divide...
+#define NUMPY_NARY_FUNC_NAME true_divide
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::div
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/true_divide/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/true_divide/accumulate.hpp
new file mode 100644
index 00000000000..be66704419e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/true_divide/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_TRUE_DIVIDE_ACCUMULATE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_TRUE_DIVIDE_ACCUMULATE_HPP
+
+#define UFUNC_NAME true_divide
+#include "pythonic/include/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/trunc.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/trunc.hpp
new file mode 100644
index 00000000000..a5ec9f94295
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/trunc.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_TRUNC_HPP
+#define PYTHONIC_INCLUDE_NUMPY_TRUNC_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME trunc
+#define NUMPY_NARY_FUNC_SYM xsimd::trunc
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ubyte.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ubyte.hpp
new file mode 100644
index 00000000000..51327e593b5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ubyte.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_UBYTE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_UBYTE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/meta.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/types/numpy_op_helper.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ unsigned char ubyte();
+ template <class V>
+ unsigned char ubyte(V v);
+ }
+
+#define NUMPY_NARY_FUNC_NAME ubyte
+#define NUMPY_NARY_FUNC_SYM details::ubyte
+#define NUMPY_NARY_EXTRA_METHOD using type = unsigned char;
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ufunc_accumulate.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ufunc_accumulate.hpp
new file mode 100644
index 00000000000..ffbfa83fb51
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ufunc_accumulate.hpp
@@ -0,0 +1,26 @@
+#ifndef UFUNC_NAME
+#error missing UFUNC_NAME
+#endif
+
+// clang-format off
+#include INCLUDE_FILE(pythonic/include/numpy,UFUNC_NAME)
+// clang-format on
+#include "pythonic/include/utils/functor.hpp"
+#include <pythonic/include/numpy/partial_sum.hpp>
+
+#include <utility>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace UFUNC_NAME
+ {
+ template <class T,
+ class dtype = numpy::result_dtype<numpy::functor::UFUNC_NAME, T>>
+ auto accumulate(T &&a, long axis = 0, dtype d = dtype())
+ -> decltype(partial_sum<numpy::functor::UFUNC_NAME>(std::forward<T>(a),
+ axis, d));
+ DEFINE_FUNCTOR(pythonic::numpy::UFUNC_NAME, accumulate);
+ }
+}
+PYTHONIC_NS_END
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ufunc_reduce.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ufunc_reduce.hpp
new file mode 100644
index 00000000000..f7d6c7caf04
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ufunc_reduce.hpp
@@ -0,0 +1,42 @@
+#ifndef UFUNC_NAME
+#error missing UFUNC_NAME
+#endif
+#ifndef UFUNC_INAME
+#error missing UFUNC_INAME
+#endif
+
+// clang-format off
+#include INCLUDE_FILE(pythonic/include/operator_,UFUNC_INAME)
+// clang-format on
+#include "pythonic/include/numpy/reduce.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace UFUNC_NAME
+ {
+
+ template <class Arg>
+ auto reduce(Arg &&arg)
+ -> decltype(numpy::reduce<operator_::functor::UFUNC_INAME>(
+ std::forward<Arg>(arg), 0L))
+ {
+ return numpy::reduce<operator_::functor::UFUNC_INAME>(
+ std::forward<Arg>(arg), 0L);
+ }
+ template <class... Args>
+ auto reduce(Args &&... args) -> typename std::enable_if<
+ sizeof...(Args) != 1,
+ decltype(numpy::reduce<operator_::functor::UFUNC_INAME>(
+ std::forward<Args>(args)...))>::type
+ {
+ return numpy::reduce<operator_::functor::UFUNC_INAME>(
+ std::forward<Args>(args)...);
+ }
+
+ DEFINE_FUNCTOR(pythonic::numpy::UFUNC_NAME, reduce);
+ }
+}
+PYTHONIC_NS_END
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/uint.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/uint.hpp
new file mode 100644
index 00000000000..ec4773dae2c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/uint.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_UINT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_UINT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/meta.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/types/numpy_op_helper.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+ unsigned long uint();
+ template <class V>
+ unsigned long uint(V v);
+ }
+
+#define NUMPY_NARY_FUNC_NAME uint
+#define NUMPY_NARY_FUNC_SYM details::uint
+#define NUMPY_NARY_EXTRA_METHOD using type = unsigned long;
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/uintc.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/uintc.hpp
new file mode 100644
index 00000000000..027326c312e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/uintc.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_UINTC_HPP
+#define PYTHONIC_INCLUDE_NUMPY_UINTC_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/meta.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/types/numpy_op_helper.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ unsigned uintc();
+ template <class V>
+ unsigned uintc(V v);
+ }
+
+#define NUMPY_NARY_FUNC_NAME uintc
+#define NUMPY_NARY_FUNC_SYM details::uintc
+#define NUMPY_NARY_EXTRA_METHOD using type = unsigned;
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/uintp.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/uintp.hpp
new file mode 100644
index 00000000000..f8184e349a0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/uintp.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_UINTP_HPP
+#define PYTHONIC_INCLUDE_NUMPY_UINTP_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/meta.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/types/numpy_op_helper.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ uintptr_t uintp();
+ template <class V>
+ uintptr_t uintp(V v);
+ }
+
+#define NUMPY_NARY_FUNC_NAME uintp
+#define NUMPY_NARY_FUNC_SYM details::uintp
+#define NUMPY_NARY_EXTRA_METHOD using type = uintptr_t;
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ulonglong.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ulonglong.hpp
new file mode 100644
index 00000000000..8811bd2cc90
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ulonglong.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ULONGLONG_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ULONGLONG_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/meta.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/types/numpy_op_helper.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ unsigned long long ulonglong();
+ template <class V>
+ unsigned long long ulonglong(V v);
+ }
+
+#define NUMPY_NARY_FUNC_NAME ulonglong
+#define NUMPY_NARY_FUNC_SYM details::ulonglong
+#define NUMPY_NARY_EXTRA_METHOD using type = unsigned long long;
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/union1d.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/union1d.hpp
new file mode 100644
index 00000000000..5b578c3d9b8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/union1d.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_UNION1D_HPP
+#define PYTHONIC_INCLUDE_NUMPY_UNION1D_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E, class F>
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::pshape<long>>
+ union1d(E const &e, F const &f);
+
+ DEFINE_FUNCTOR(pythonic::numpy, union1d)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/unique.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/unique.hpp
new file mode 100644
index 00000000000..b4d8b0cc2fa
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/unique.hpp
@@ -0,0 +1,113 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_UNIQUE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_UNIQUE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/tuple.hpp"
+#include "pythonic/include/types/immediate.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ types::ndarray<typename E::dtype, types::pshape<long>> unique(E const &expr);
+
+ template <class E>
+ std::tuple<types::ndarray<typename E::dtype, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>>
+ unique(E const &expr, types::true_immediate return_index);
+
+ template <class E>
+ types::ndarray<typename E::dtype, types::pshape<long>>
+ unique(E const &expr, types::false_immediate return_index);
+
+ template <class E>
+ std::tuple<types::ndarray<typename E::dtype, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>>
+ unique(E const &expr, types::false_immediate return_index,
+ types::true_immediate return_inverse);
+
+ template <class E>
+ types::ndarray<typename E::dtype, types::pshape<long>>
+ unique(E const &expr, types::false_immediate return_index,
+ types::false_immediate return_inverse);
+
+ template <class E>
+ std::tuple<types::ndarray<typename E::dtype, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>>
+ unique(E const &expr, types::true_immediate return_index,
+ types::false_immediate return_inverse);
+
+ template <class E>
+ std::tuple<types::ndarray<typename E::dtype, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>>
+ unique(E const &expr, types::true_immediate return_index,
+ types::true_immediate return_inverse);
+
+ template <class E>
+ std::tuple<types::ndarray<typename E::dtype, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>>
+ unique(E const &expr, types::true_immediate return_index,
+ types::true_immediate return_inverse,
+ types::true_immediate return_counts);
+
+ template <class E>
+ std::tuple<types::ndarray<typename E::dtype, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>>
+ unique(E const &expr, types::true_immediate return_index,
+ types::true_immediate return_inverse,
+ types::false_immediate return_counts);
+
+ template <class E>
+ std::tuple<types::ndarray<typename E::dtype, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>>
+ unique(E const &expr, types::true_immediate return_index,
+ types::false_immediate return_inverse,
+ types::false_immediate return_counts);
+
+ template <class E>
+ std::tuple<types::ndarray<typename E::dtype, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>>
+ unique(E const &expr, types::true_immediate return_index,
+ types::false_immediate return_inverse,
+ types::true_immediate return_counts);
+
+ template <class E>
+ std::tuple<types::ndarray<typename E::dtype, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>>
+ unique(E const &expr, types::false_immediate return_index,
+ types::true_immediate return_inverse,
+ types::false_immediate return_counts);
+
+ template <class E>
+ std::tuple<types::ndarray<typename E::dtype, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>>
+ unique(E const &expr, types::false_immediate return_index,
+ types::true_immediate return_inverse,
+ types::true_immediate return_counts);
+
+ template <class E>
+ types::ndarray<typename E::dtype, types::pshape<long>>
+ unique(E const &expr, types::false_immediate return_index,
+ types::false_immediate return_inverse,
+ types::false_immediate return_counts);
+
+ template <class E>
+ std::tuple<types::ndarray<typename E::dtype, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>>
+ unique(E const &expr, types::false_immediate return_index,
+ types::false_immediate return_inverse,
+ types::true_immediate return_counts);
+
+ DEFINE_FUNCTOR(pythonic::numpy, unique)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/unravel_index.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/unravel_index.hpp
new file mode 100644
index 00000000000..9f585f10e12
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/unravel_index.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_UNRAVEL_INDEX_HPP
+#define PYTHONIC_INCLUDE_NUMPY_UNRAVEL_INDEX_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/str.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E, class S>
+ typename std::enable_if<std::is_scalar<E>::value,
+ types::array<long, std::tuple_size<S>::value>>::type
+ unravel_index(E const &expr, S const &shape, types::str const &order = "C");
+
+ DEFINE_FUNCTOR(pythonic::numpy, unravel_index);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/unwrap.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/unwrap.hpp
new file mode 100644
index 00000000000..1615cf59f9a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/unwrap.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_UNWRAP_HPP
+#define PYTHONIC_INCLUDE_NUMPY_UNWRAP_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/int_.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/numpy/pi.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ types::ndarray<double, typename E::shape_t> unwrap(E const &expr,
+ double discont = pi);
+
+ DEFINE_FUNCTOR(pythonic::numpy, unwrap)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/ushort.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/ushort.hpp
new file mode 100644
index 00000000000..11d29800173
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/ushort.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_USHORT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_USHORT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/meta.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+#include "pythonic/include/types/numpy_op_helper.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ unsigned short ushort();
+ template <class V>
+ unsigned short ushort(V v);
+ }
+
+#define NUMPY_NARY_FUNC_NAME ushort
+#define NUMPY_NARY_FUNC_SYM details::ushort
+#define NUMPY_NARY_EXTRA_METHOD using type = unsigned short;
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/var.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/var.hpp
new file mode 100644
index 00000000000..104a4f64015
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/var.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_VAR_HPP
+#define PYTHONIC_INCLUDE_NUMPY_VAR_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/builtins/None.hpp"
+#include "pythonic/include/numpy/add.hpp"
+#include "pythonic/include/numpy/mean.hpp"
+#include "pythonic/include/numpy/sum.hpp"
+
+#include <algorithm>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ using var_type = typename std::conditional<
+ std::is_integral<typename E::dtype>::value, double,
+ decltype(std::real(std::declval<typename E::dtype>()))>::type;
+
+ template <class E>
+ auto var(E const &expr, types::none_type axis = builtins::None,
+ types::none_type dtype = builtins::None,
+ types::none_type out = builtins::None, long ddof = 0)
+ -> decltype(var_type<E>(std::real(mean(expr))));
+
+ template <class E>
+ auto var(E const &expr, long axis, types::none_type dtype = builtins::None,
+ types::none_type out = builtins::None, long ddof = 0) ->
+ typename assignable<decltype(var_type<E>() * mean(expr, axis))>::type;
+
+ DEFINE_FUNCTOR(pythonic::numpy, var);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/vdot.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/vdot.hpp
new file mode 100644
index 00000000000..67f9ffdad93
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/vdot.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_VDOT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_VDOT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/numpy/dot.hpp"
+#include "pythonic/include/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class U, class V>
+ auto vdot(U const &u, V const &v)
+ -> decltype(functor::dot{}(functor::asarray{}(u).flat(),
+ functor::asarray{}(v).flat()));
+
+ DEFINE_FUNCTOR(pythonic::numpy, vdot);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/vectorize.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/vectorize.hpp
new file mode 100644
index 00000000000..14e1fead586
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/vectorize.hpp
@@ -0,0 +1,35 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_VECTORIZE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_VECTORIZE_HPP
+
+#include "pythonic/include/types/numpy_expr.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class F>
+ struct vectorized {
+ using callable = void;
+ template <typename... T>
+ auto operator()(T &&...args) const ->
+ typename std::enable_if<!types::valid_numexpr_parameters<
+ typename std::decay<T>::type...>::value,
+ decltype(F{}(std::forward<T>(args)...))>::type;
+
+ template <class... E>
+ typename std::enable_if<
+ types::valid_numexpr_parameters<typename std::decay<E>::type...>::value,
+ types::numpy_expr<F,
+ typename types::adapt_type<E, E...>::type...>>::type
+ operator()(E &&...args) const;
+ };
+
+ template <class F>
+ vectorized<F> vectorize(F const &);
+
+ DEFINE_FUNCTOR(pythonic::numpy, vectorize);
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/vstack.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/vstack.hpp
new file mode 100644
index 00000000000..38afc536988
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/vstack.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_VSTACK_HPP
+#define PYTHONIC_INCLUDE_NUMPY_VSTACK_HPP
+
+#include <pythonic/include/numpy/concatenate.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace impl
+ {
+ template <class T>
+ using vstack_helper = decltype(concatenate(std::declval<T>(), 0));
+ }
+
+ template <class ArraySequence>
+ auto vstack(ArraySequence &&seq) ->
+ typename std::enable_if<(impl::vstack_helper<ArraySequence>::value > 1),
+ impl::vstack_helper<ArraySequence>>::type;
+
+ // according to the numpy.vstack doc:
+ // Equivalent to ``np.concatenate(tup, axis=0)`` if `tup` contains arrays
+ // that
+ // are at least 2-dimensional.
+ //
+ // the enable if is there to match this behavior
+ template <class ArraySequence>
+ auto vstack(ArraySequence &&seq) -> typename std::enable_if<
+ (impl::vstack_helper<ArraySequence>::value == 1),
+ decltype(std::declval<impl::vstack_helper<ArraySequence>>().reshape(
+ std::declval<types::array<long, 2>>()))>::type;
+
+ DEFINE_FUNCTOR(pythonic::numpy, vstack);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/where.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/where.hpp
new file mode 100644
index 00000000000..b75fa19621e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/where.hpp
@@ -0,0 +1,33 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_WHERE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_WHERE_HPP
+
+#include "pythonic/include/numpy/asarray.hpp"
+#include "pythonic/include/numpy/nonzero.hpp"
+#include "pythonic/include/numpy/copy.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace impl
+ {
+ template <class E, class F, class G>
+ typename __combined<F, G>::type where(E const &cond, F const &true_,
+ G const &false_);
+ }
+
+#define NUMPY_NARY_EXTRA_METHOD \
+ template <class E> \
+ auto operator()(E && expr)->decltype(nonzero{}(std::forward<E>(expr))) \
+ { \
+ return nonzero{}(std::forward<E>(expr)); \
+ }
+
+#define NUMPY_NARY_FUNC_NAME where
+#define NUMPY_NARY_FUNC_SYM impl::where
+#define NUMPY_NARY_RESHAPE_MODE reshape_type
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/zeros.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/zeros.hpp
new file mode 100644
index 00000000000..d525edaff69
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/zeros.hpp
@@ -0,0 +1,33 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ZEROS_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ZEROS_HPP
+
+#include "pythonic/include/numpy/float64.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class dtype = functor::float64>
+ typename dtype::type
+ zeros(std::tuple<> const &shape, dtype d = dtype());
+
+ template <class pS, class dtype = functor::float64>
+ types::ndarray<typename dtype::type, sutils::shape_t<pS>>
+ zeros(pS const &shape, dtype d = dtype());
+
+ template <class dtype = functor::float64>
+ types::ndarray<typename dtype::type, types::pshape<long>>
+ zeros(long size, dtype d = dtype());
+
+ template <long N, class dtype = functor::float64>
+ types::ndarray<typename dtype::type,
+ types::pshape<std::integral_constant<long, N>>>
+ zeros(std::integral_constant<long, N>, dtype d = dtype());
+
+ DEFINE_FUNCTOR(pythonic::numpy, zeros);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/numpy/zeros_like.hpp b/contrib/python/pythran/pythran/pythonic/include/numpy/zeros_like.hpp
new file mode 100644
index 00000000000..80e063feef8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/numpy/zeros_like.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_INCLUDE_NUMPY_ZEROSLIKE_HPP
+#define PYTHONIC_INCLUDE_NUMPY_ZEROSLIKE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/numpy/zeros.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class E, class dtype>
+ auto zeros_like(E const &expr, dtype d = dtype())
+ -> decltype(zeros(sutils::getshape(expr), d));
+
+ template <class E>
+ auto zeros_like(E const &expr, types::none_type d = builtins::None)
+ -> decltype(zeros(sutils::getshape(expr),
+ types::dtype_t<typename E::dtype>()));
+
+ DEFINE_FUNCTOR(pythonic::numpy, zeros_like)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/omp/get_num_threads.hpp b/contrib/python/pythran/pythran/pythonic/include/omp/get_num_threads.hpp
new file mode 100644
index 00000000000..48262f66296
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/omp/get_num_threads.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_OMP_GET_NUM_THREADS_HPP
+#define PYTHONIC_INCLUDE_OMP_GET_NUM_THREADS_HPP
+
+#include <omp.h>
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace omp
+{
+
+ long get_num_threads();
+
+ DEFINE_FUNCTOR(pythonic::omp, get_num_threads);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/omp/get_thread_num.hpp b/contrib/python/pythran/pythran/pythonic/include/omp/get_thread_num.hpp
new file mode 100644
index 00000000000..36829d9b259
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/omp/get_thread_num.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_OMP_GET_THREAD_NUM_HPP
+#define PYTHONIC_INCLUDE_OMP_GET_THREAD_NUM_HPP
+
+#include <omp.h>
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace omp
+{
+
+ long get_thread_num();
+
+ DEFINE_FUNCTOR(pythonic::omp, get_thread_num);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/omp/get_wtick.hpp b/contrib/python/pythran/pythran/pythonic/include/omp/get_wtick.hpp
new file mode 100644
index 00000000000..5deab26d53b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/omp/get_wtick.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_OMP_GET_WTICK_HPP
+#define PYTHONIC_INCLUDE_OMP_GET_WTICK_HPP
+
+#include <omp.h>
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace omp
+{
+ long get_wtick();
+
+ DEFINE_FUNCTOR(pythonic::omp, get_wtick);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/omp/get_wtime.hpp b/contrib/python/pythran/pythran/pythonic/include/omp/get_wtime.hpp
new file mode 100644
index 00000000000..68760a6cb0f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/omp/get_wtime.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_OMP_GET_WTIME_HPP
+#define PYTHONIC_INCLUDE_OMP_GET_WTIME_HPP
+
+#include <omp.h>
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace omp
+{
+
+ long get_wtime();
+
+ DEFINE_FUNCTOR(pythonic::omp, get_wtime);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/omp/in_parallel.hpp b/contrib/python/pythran/pythran/pythonic/include/omp/in_parallel.hpp
new file mode 100644
index 00000000000..0fc99b376b5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/omp/in_parallel.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_OMP_IN_PARALLEL_HPP
+#define PYTHONIC_INCLUDE_OMP_IN_PARALLEL_HPP
+
+#include <omp.h>
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace omp
+{
+ bool in_parallel();
+
+ DEFINE_FUNCTOR(pythonic::omp, in_parallel);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/omp/set_nested.hpp b/contrib/python/pythran/pythran/pythonic/include/omp/set_nested.hpp
new file mode 100644
index 00000000000..2760fe13fc1
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/omp/set_nested.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_OMP_SET_NESTED_HPP
+#define PYTHONIC_INCLUDE_OMP_SET_NESTED_HPP
+
+#include <omp.h>
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace omp
+{
+
+ void set_nested(long val);
+
+ DEFINE_FUNCTOR(pythonic::omp, set_nested);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/omp/set_num_threads.hpp b/contrib/python/pythran/pythran/pythonic/include/omp/set_num_threads.hpp
new file mode 100644
index 00000000000..e31ac8ae962
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/omp/set_num_threads.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_OMP_SET_NUM_THREADS_HPP
+#define PYTHONIC_INCLUDE_OMP_SET_NUM_THREADS_HPP
+
+#include <omp.h>
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace omp
+{
+
+ void set_num_threads(long);
+
+ DEFINE_FUNCTOR(pythonic::omp, set_num_threads);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__abs__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__abs__.hpp
new file mode 100644
index 00000000000..add04278d88
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__abs__.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_ABS__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_ABS__HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/builtins/abs.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__abs__, builtins::functor::abs);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__add__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__add__.hpp
new file mode 100644
index 00000000000..1814c94b2d3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__add__.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_ADD__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_ADD__HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/operator_/add.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__add__, add);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__and__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__and__.hpp
new file mode 100644
index 00000000000..97d7b82ab77
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__and__.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_AND__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_AND__HPP
+
+#include "pythonic/include/operator_/and_.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ USING_FUNCTOR(__and__, and_);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__concat__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__concat__.hpp
new file mode 100644
index 00000000000..ae2a0a3c7c1
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__concat__.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_CONCAT__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_CONCAT__HPP
+
+#include "pythonic/include/operator_/concat.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ USING_FUNCTOR(__concat__, concat);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__contains__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__contains__.hpp
new file mode 100644
index 00000000000..2434c7e1eda
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__contains__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_CONTAINS__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_CONTAINS__HPP
+
+#include "pythonic/include/operator_/contains.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__contains__, contains);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__delitem__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__delitem__.hpp
new file mode 100644
index 00000000000..ef9a8bc8bd5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__delitem__.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_DELITEM__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_DELITEM__HPP
+
+#include "pythonic/include/operator_/delitem.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ USING_FUNCTOR(__delitem__, delitem);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__div__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__div__.hpp
new file mode 100644
index 00000000000..edbd0856864
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__div__.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_DIV__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_DIV__HPP
+
+#include "pythonic/include/operator_/div.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ USING_FUNCTOR(__div__, div);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__eq__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__eq__.hpp
new file mode 100644
index 00000000000..58fda8c95b8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__eq__.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_EQ__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_EQ__HPP
+
+#include "pythonic/include/operator_/eq.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ USING_FUNCTOR(__eq__, eq);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__floordiv__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__floordiv__.hpp
new file mode 100644
index 00000000000..6ce4426e8d2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__floordiv__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_FLOORDIV__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_FLOORDIV__HPP
+
+#include "pythonic/include/operator_/floordiv.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__floordiv__, floordiv);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__ge__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__ge__.hpp
new file mode 100644
index 00000000000..9a078e1d416
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__ge__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_GE__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_GE__HPP
+
+#include "pythonic/include/operator_/ge.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__ge__, ge);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__getitem__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__getitem__.hpp
new file mode 100644
index 00000000000..f8044c77958
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__getitem__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_GETITEM__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_GETITEM__HPP
+
+#include "pythonic/include/operator_/getitem.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__getitem__, getitem);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__gt__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__gt__.hpp
new file mode 100644
index 00000000000..4d5178c6bbd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__gt__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_GT__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_GT__HPP
+
+#include "pythonic/include/operator_/gt.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__gt__, gt);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__iadd__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__iadd__.hpp
new file mode 100644
index 00000000000..35b80b0f0e9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__iadd__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_IADD__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_IADD__HPP
+
+#include "pythonic/include/operator_/iadd.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__iadd__, iadd);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__iand__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__iand__.hpp
new file mode 100644
index 00000000000..18945fc1a89
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__iand__.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_IAND__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_IAND__HPP
+
+#include "pythonic/include/operator_/iand.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ USING_FUNCTOR(__iand__, iand);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__iconcat__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__iconcat__.hpp
new file mode 100644
index 00000000000..d7997a8ad04
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__iconcat__.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_ICONCAT__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_ICONCAT__HPP
+
+#include "pythonic/include/operator_/iconcat.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ USING_FUNCTOR(__iconcat__, iconcat);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__idiv__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__idiv__.hpp
new file mode 100644
index 00000000000..9720017c2a0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__idiv__.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_IDIV__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_IDIV__HPP
+
+#include "pythonic/include/operator_/idiv.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ USING_FUNCTOR(__idiv__, idiv);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__ifloordiv__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__ifloordiv__.hpp
new file mode 100644
index 00000000000..08614a0dfc7
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__ifloordiv__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_IFLOORDIV__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_IFLOORDIV__HPP
+
+#include "pythonic/include/operator_/ifloordiv.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__ifloordiv__, ifloordiv);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__ilshift__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__ilshift__.hpp
new file mode 100644
index 00000000000..bdf4749a263
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__ilshift__.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_ILSHIFT__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_ILSHIFT__HPP
+
+#include "pythonic/include/operator_/ilshift.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ USING_FUNCTOR(__ilshift__, ilshift);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__imod__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__imod__.hpp
new file mode 100644
index 00000000000..aca1f389b3c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__imod__.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_IMOD__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_IMOD__HPP
+
+#include "pythonic/include/operator_/imod.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ USING_FUNCTOR(__imod__, imod);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__imul__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__imul__.hpp
new file mode 100644
index 00000000000..7639801bda4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__imul__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_IMUL__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_IMUL__HPP
+
+#include "pythonic/include/operator_/imul.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__imul__, imul);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__inv__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__inv__.hpp
new file mode 100644
index 00000000000..f85928015e1
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__inv__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_INV__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_INV__HPP
+
+#include "pythonic/include/operator_/invert.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__inv__, invert);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__invert__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__invert__.hpp
new file mode 100644
index 00000000000..1e654f9c5b8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__invert__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_INVERT__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_INVERT__HPP
+
+#include "pythonic/include/operator_/invert.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__invert__, invert);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__ior__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__ior__.hpp
new file mode 100644
index 00000000000..864f4de5409
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__ior__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_IOR__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_IOR__HPP
+
+#include "pythonic/include/operator_/ior.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__ior__, ior);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__ipow__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__ipow__.hpp
new file mode 100644
index 00000000000..aa78e384edd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__ipow__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_IPOW__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_IPOW__HPP
+
+#include "pythonic/include/operator_/ipow.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__ipow__, ipow);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__irshift__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__irshift__.hpp
new file mode 100644
index 00000000000..44cab226d77
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__irshift__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_IRSHIFT__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_IRSHIFT__HPP
+
+#include "pythonic/include/operator_/irshift.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__irshift__, irshift);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__isub__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__isub__.hpp
new file mode 100644
index 00000000000..06f44bd4d0d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__isub__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_ISUB__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_ISUB__HPP
+
+#include "pythonic/include/operator_/isub.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__isub__, isub);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__itruediv__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__itruediv__.hpp
new file mode 100644
index 00000000000..2b00a003ffc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__itruediv__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_ITRUEDIV__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_ITRUEDIV__HPP
+
+#include "pythonic/include/operator_/itruediv.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__itruediv__, itruediv);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__ixor__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__ixor__.hpp
new file mode 100644
index 00000000000..b6b0a2a23be
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__ixor__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_IXOR__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_IXOR__HPP
+
+#include "pythonic/include/operator_/ixor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__ixor__, ixor);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__le__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__le__.hpp
new file mode 100644
index 00000000000..7e2c1c09bee
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__le__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_LE__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_LE__HPP
+
+#include "pythonic/include/operator_/le.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__le__, le);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__lshift__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__lshift__.hpp
new file mode 100644
index 00000000000..fcdee0bff9c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__lshift__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_LSHIFT__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_LSHIFT__HPP
+
+#include "pythonic/include/operator_/lshift.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__lshift__, lshift);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__lt__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__lt__.hpp
new file mode 100644
index 00000000000..a64405c70e9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__lt__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_LT__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_LT__HPP
+
+#include "pythonic/include/operator_/lt.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__lt__, lt);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__matmul__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__matmul__.hpp
new file mode 100644
index 00000000000..e5a38ec8b71
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__matmul__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_MATMUL__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_MATMUL__HPP
+
+#include "pythonic/include/operator_/matmul.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__mul__, matmul);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__mod__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__mod__.hpp
new file mode 100644
index 00000000000..581244f9055
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__mod__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_MOD__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_MOD__HPP
+
+#include "pythonic/include/operator_/mod.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__mod__, mod);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__mul__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__mul__.hpp
new file mode 100644
index 00000000000..0727d223ca2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__mul__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_MUL__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_MUL__HPP
+
+#include "pythonic/include/operator_/mul.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__mul__, mul);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__ne__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__ne__.hpp
new file mode 100644
index 00000000000..0be7c814b69
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__ne__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_NE__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_NE__HPP
+
+#include "pythonic/include/operator_/ne.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__ne__, ne);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__neg__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__neg__.hpp
new file mode 100644
index 00000000000..adb6f47e501
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__neg__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_NEG__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_NEG__HPP
+
+#include "pythonic/include/operator_/neg.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__neg__, neg);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__not__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__not__.hpp
new file mode 100644
index 00000000000..a08048f6238
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__not__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_NOT__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_NOT__HPP
+
+#include "pythonic/include/operator_/not_.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__not__, not_);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__or__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__or__.hpp
new file mode 100644
index 00000000000..1ba2f445b27
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__or__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_OR__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_OR__HPP
+
+#include "pythonic/include/operator_/or_.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__or__, or_);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__pos__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__pos__.hpp
new file mode 100644
index 00000000000..5631e5226c4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__pos__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_POS__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_POS__HPP
+
+#include "pythonic/include/operator_/pos.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__pos__, pos);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__rshift__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__rshift__.hpp
new file mode 100644
index 00000000000..1fa359853f9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__rshift__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_RSHIFT__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_RSHIFT__HPP
+
+#include "pythonic/include/operator_/rshift.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__rshift__, rshift);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__sub__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__sub__.hpp
new file mode 100644
index 00000000000..e16a61fa13b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__sub__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_SUB__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_SUB__HPP
+
+#include "pythonic/include/operator_/sub.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__sub__, sub);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__truediv__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__truediv__.hpp
new file mode 100644
index 00000000000..fdf8d716bf6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__truediv__.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_TRUEDIV__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_TRUEDIV__HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/operator_/truediv.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(__truediv__, truediv)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/__xor__.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/__xor__.hpp
new file mode 100644
index 00000000000..9a7c4c633e2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/__xor__.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_XOR__HPP
+#define PYTHONIC_INCLUDE_OPERATOR_XOR__HPP
+
+#include "pythonic/include/operator_/xor_.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace operator_
+{
+ USING_FUNCTOR(__xor__, xor_);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/abs.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/abs.hpp
new file mode 100644
index 00000000000..92eda417cd8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/abs.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_ABS_HPP
+#define PYTHONIC_INCLUDE_OPERATOR_ABS_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/builtins/abs.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(abs, builtins::functor::abs);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/concat.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/concat.hpp
new file mode 100644
index 00000000000..b4e5979e698
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/concat.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_CONCAT_HPP
+#define PYTHONIC_INCLUDE_OPERATOR_CONCAT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ template <class A, class B>
+ auto concat(A &&a, B &&b)
+ -> decltype(std::forward<A>(a) + std::forward<B>(b));
+
+ DEFINE_FUNCTOR(pythonic::operator_, concat);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/contains.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/contains.hpp
new file mode 100644
index 00000000000..cb2b7307d74
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/contains.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_CONTAINS_HPP
+#define PYTHONIC_INCLUDE_OPERATOR_CONTAINS_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/builtins/in.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ template <class A, class B>
+ auto contains(A &&a, B &&b)
+ -> decltype(in(std::forward<A>(a), std::forward<B>(b)));
+
+ DEFINE_FUNCTOR(pythonic::operator_, contains);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/countOf.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/countOf.hpp
new file mode 100644
index 00000000000..bb941666fed
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/countOf.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_COUNTOF_HPP
+#define PYTHONIC_INCLUDE_OPERATOR_COUNTOF_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <algorithm>
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ template <class A, class B>
+ long countOf(A &&a, B &&b);
+
+ DEFINE_FUNCTOR(pythonic::operator_, countOf);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/delitem.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/delitem.hpp
new file mode 100644
index 00000000000..56ff597978f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/delitem.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_DELITEM_HPP
+#define PYTHONIC_INCLUDE_OPERATOR_DELITEM_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/builtins/None.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ template <class A, class B>
+ types::none_type delitem(A &&a, B &&b);
+
+ DEFINE_FUNCTOR(pythonic::operator_, delitem);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/getitem.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/getitem.hpp
new file mode 100644
index 00000000000..380007aa3af
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/getitem.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_GETITEM_HPP
+#define PYTHONIC_INCLUDE_OPERATOR_GETITEM_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ template <class A, class B>
+ auto getitem(A &&a, B &&b)
+ -> decltype(std::forward<A>(a)[std::forward<B>(b)]);
+
+ DEFINE_FUNCTOR(pythonic::operator_, getitem);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/iconcat.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/iconcat.hpp
new file mode 100644
index 00000000000..96266ca2639
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/iconcat.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_ICONCAT_HPP
+#define PYTHONIC_INCLUDE_OPERATOR_ICONCAT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/list.hpp"
+#include "pythonic/include/types/set.hpp"
+#include "pythonic/include/types/dict.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ template <class A, class B>
+ A iconcat(A a, B const &b);
+
+ template <class A>
+ auto iconcat(types::empty_list a, types::list<A> b) -> decltype(b);
+
+ template <class K, class V>
+ auto iconcat(types::empty_dict a, types::dict<K, V> b) -> decltype(b);
+
+ template <class A>
+ auto iconcat(types::empty_set a, types::set<A> b) -> decltype(b);
+
+ DEFINE_FUNCTOR(pythonic::operator_, iconcat);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/ifloordiv.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/ifloordiv.hpp
new file mode 100644
index 00000000000..721565a6478
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/ifloordiv.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_IFLOORDIV_HPP
+#define PYTHONIC_INCLUDE_OPERATOR_IFLOORDIV_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/operator_/mod.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ template <class A, class B>
+ A ifloordiv(A &&a, B &&b);
+
+ template <class A, class B>
+ auto ifloordiv(A const &a, B &&b) -> decltype((a - mod(a, b)) / b);
+
+ DEFINE_FUNCTOR(pythonic::operator_, ifloordiv);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/ilshift.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/ilshift.hpp
new file mode 100644
index 00000000000..12066c7604d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/ilshift.hpp
@@ -0,0 +1,9 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_ILSHIFT_HPP
+#define PYTHONIC_INCLUDE_OPERATOR_ILSHIFT_HPP
+
+#define OPERATOR_NAME ilshift
+#define OPERATOR_SYMBOL <<
+#define OPERATOR_ISYMBOL <<=
+#include "pythonic/include/operator_/icommon.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/imatmul.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/imatmul.hpp
new file mode 100644
index 00000000000..4ae55bb819c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/imatmul.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_IMATMUL_HPP
+#define PYTHONIC_INCLUDE_OPERATOR_IMATMUL_HPP
+
+#include "pythonic/include/numpy/dot.hpp"
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ template <class A, class B>
+ A imatmul(A const &a, B &&b);
+ template <class A, class B>
+ A &imatmul(A &a, B &&b);
+
+ DEFINE_FUNCTOR(pythonic::operator_, imatmul);
+} // namespace operator_
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/imod.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/imod.hpp
new file mode 100644
index 00000000000..477d80afbb9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/imod.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_IMOD_HPP
+#define PYTHONIC_INCLUDE_OPERATOR_IMOD_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ template <class A, class B>
+ A &imod(A &a, B &&b);
+ template <class A, class B>
+ A imod(A const &a, B &&b);
+
+ DEFINE_FUNCTOR(pythonic::operator_, imod);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/indexOf.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/indexOf.hpp
new file mode 100644
index 00000000000..b66ff2b5bdc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/indexOf.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_INDEXOF_HPP
+#define PYTHONIC_INCLUDE_OPERATOR_INDEXOF_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ template <class A, class B>
+ long indexOf(A &&a, B &&b);
+
+ DEFINE_FUNCTOR(pythonic::operator_, indexOf);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/inv.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/inv.hpp
new file mode 100644
index 00000000000..1f96938880e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/inv.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_INV_HPP
+#define PYTHONIC_INCLUDE_OPERATOR_INV_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/operator_/invert.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ USING_FUNCTOR(inv, invert);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/invert.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/invert.hpp
new file mode 100644
index 00000000000..e647e6f5496
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/invert.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_INVERT_HPP
+#define PYTHONIC_INCLUDE_OPERATOR_INVERT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ template <class A>
+ auto invert(A &&a) -> decltype(~std::forward<A>(a));
+
+ DEFINE_FUNCTOR(pythonic::operator_, invert);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/ipow.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/ipow.hpp
new file mode 100644
index 00000000000..e6ab178fb33
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/ipow.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_IPOW_HPP
+#define PYTHONIC_INCLUDE_OPERATOR_IPOW_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/builtins/pow.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ template <class A, class B>
+ A ipow(A const &a, B &&b);
+ template <class A, class B>
+ A &ipow(A &a, B &&b);
+
+ DEFINE_FUNCTOR(pythonic::operator_, ipow);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/irshift.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/irshift.hpp
new file mode 100644
index 00000000000..62c55c54759
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/irshift.hpp
@@ -0,0 +1,9 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_IRSHIFT_HPP
+#define PYTHONIC_INCLUDE_OPERATOR_IRSHIFT_HPP
+
+#define OPERATOR_NAME irshift
+#define OPERATOR_SYMBOL >>
+#define OPERATOR_ISYMBOL >>=
+#include "pythonic/include/operator_/icommon.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/is_.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/is_.hpp
new file mode 100644
index 00000000000..455ad489e1f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/is_.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_IS_HPP
+#define PYTHONIC_INCLUDE_OPERATOR_IS_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/builtins/id.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ template <class A, class B>
+ auto is_(A &&a, B &&b) -> decltype(builtins::id(std::forward<A>(a)) ==
+ builtins::id(std::forward<B>(b)));
+
+ DEFINE_FUNCTOR(pythonic::operator_, is_);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/is_not.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/is_not.hpp
new file mode 100644
index 00000000000..f1fe2132ace
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/is_not.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_ISNOT_HPP
+#define PYTHONIC_INCLUDE_OPERATOR_ISNOT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ template <class A, class B>
+ auto is_not(A &&a, B &&b) -> decltype(builtins::id(std::forward<A>(a)) !=
+ builtins::id(std::forward<B>(b)));
+
+ DEFINE_FUNCTOR(pythonic::operator_, is_not);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/itemgetter.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/itemgetter.hpp
new file mode 100644
index 00000000000..4ae3b91fa29
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/itemgetter.hpp
@@ -0,0 +1,50 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_ITEMGETTER_HPP
+#define PYTHONIC_INCLUDE_OPERATOR_ITEMGETTER_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/tuple.hpp"
+#include "pythonic/include/utils/int_.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ struct itemgetter_return {
+ long i;
+ itemgetter_return(long const &item = -1);
+ template <class A>
+ auto operator()(A const &a) const -> decltype(a[i]);
+ };
+
+ itemgetter_return itemgetter(long item);
+
+ template <typename... Types>
+ struct itemgetter_tuple_return {
+
+ std::tuple<Types...> items;
+
+ itemgetter_tuple_return(Types... items);
+
+ itemgetter_tuple_return();
+
+ template <class T, class A, size_t I>
+ void helper(T &t, A const &a, utils::int_<I>) const;
+
+ template <class T, class A>
+ void helper(T &t, A const &a, utils::int_<0>) const;
+
+ template <class A>
+ auto operator()(A const &a) const
+ -> std::tuple<typename std::remove_cv<typename std::remove_reference<
+ decltype(a[std::declval<Types>()])>::type>::type...>;
+ };
+
+ template <class... L>
+ itemgetter_tuple_return<long, long, L...>
+ itemgetter(long const &item1, long const &item2, L... items);
+
+ DEFINE_FUNCTOR(pythonic::operator_, itemgetter);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/itruediv.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/itruediv.hpp
new file mode 100644
index 00000000000..c903aca21d5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/itruediv.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_ITRUEDIV_HPP
+#define PYTHONIC_INCLUDE_OPERATOR_ITRUEDIV_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/operator_/truediv.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ template <class A, class B>
+ auto itruediv(A const &a, B &&b) -> decltype(truediv(a, std::forward<B>(b)));
+
+ template <class A, class B>
+ auto itruediv(A &a, B &&b) -> typename std::enable_if<
+ std::is_same<A, decltype(truediv(a, std::forward<B>(b)))>::value,
+ A &>::type;
+
+ template <class A, class B>
+ auto itruediv(A &a, B &&b) -> typename std::enable_if<
+ !std::is_same<A, decltype(truediv(a, std::forward<B>(b)))>::value,
+ decltype(truediv(a, std::forward<B>(b)))>::type;
+
+ DEFINE_FUNCTOR(pythonic::operator_, itruediv);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/matmul.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/matmul.hpp
new file mode 100644
index 00000000000..6800c341920
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/matmul.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_MATMUL_HPP
+#define PYTHONIC_INCLUDE_OPERATOR_MATMUL_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/numpy/dot.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ template <class A, class B>
+ auto matmul(A &&a, B &&b)
+ -> decltype(numpy::functor::dot{}(std::forward<A>(a),
+ std::forward<B>(b)));
+
+ DEFINE_FUNCTOR(pythonic::operator_, matmul);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/truediv.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/truediv.hpp
new file mode 100644
index 00000000000..b48350018e5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/truediv.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_TRUEDIV_HPP
+#define PYTHONIC_INCLUDE_OPERATOR_TRUEDIV_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ template <class A, class B>
+ auto truediv(A &&a, B &&b)
+ -> decltype(std::forward<A>(a) / (double)std::forward<B>(b));
+
+ DEFINE_FUNCTOR(pythonic::operator_, truediv);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/operator_/truth.hpp b/contrib/python/pythran/pythran/pythonic/include/operator_/truth.hpp
new file mode 100644
index 00000000000..dd7dd80fff9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/operator_/truth.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_INCLUDE_OPERATOR_TRUTH_HPP
+#define PYTHONIC_INCLUDE_OPERATOR_TRUTH_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ bool truth(bool const &a);
+
+ DEFINE_FUNCTOR(pythonic::operator_, truth);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/os/path/join.hpp b/contrib/python/pythran/pythran/pythonic/include/os/path/join.hpp
new file mode 100644
index 00000000000..74c68b58442
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/os/path/join.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_INCLUDE_OS_PATH_JOIN_HPP
+#define PYTHONIC_INCLUDE_OS_PATH_JOIN_HPP
+
+#include "pythonic/types/str.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace os
+{
+ namespace path
+ {
+
+ template <class T>
+ T join(T &&head);
+
+ template <class T, class... Types>
+ types::str join(T &&head, Types &&... tail);
+
+ DEFINE_FUNCTOR(pythonic::os::path, join);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/random/choice.hpp b/contrib/python/pythran/pythran/pythonic/include/random/choice.hpp
new file mode 100644
index 00000000000..10c93749a50
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/random/choice.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_RANDOM_CHOICE_HPP
+#define PYTHONIC_INCLUDE_RANDOM_CHOICE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/random/random.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace random
+{
+
+ template <class Seq>
+ typename Seq::value_type choice(Seq const &seq);
+
+ DEFINE_FUNCTOR(pythonic::random, choice);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/random/expovariate.hpp b/contrib/python/pythran/pythran/pythonic/include/random/expovariate.hpp
new file mode 100644
index 00000000000..28dbb3d4999
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/random/expovariate.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_RANDOM_EXPOVARIATE_HPP
+#define PYTHONIC_INCLUDE_RANDOM_EXPOVARIATE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/random/random.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace random
+{
+ double expovariate(double l);
+
+ DEFINE_FUNCTOR(pythonic::random, expovariate);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/random/gauss.hpp b/contrib/python/pythran/pythran/pythonic/include/random/gauss.hpp
new file mode 100644
index 00000000000..440a55fdb1e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/random/gauss.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_RANDOM_GAUSS_HPP
+#define PYTHONIC_INCLUDE_RANDOM_GAUSS_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/random/random.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace random
+{
+
+ double gauss(double mu, double sigma);
+
+ DEFINE_FUNCTOR(pythonic::random, gauss);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/random/randint.hpp b/contrib/python/pythran/pythran/pythonic/include/random/randint.hpp
new file mode 100644
index 00000000000..a4dcfbbd2d8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/random/randint.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_INCLUDE_RANDOM_RANDINT_HPP
+#define PYTHONIC_INCLUDE_RANDOM_RANDINT_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/random/randrange.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace random
+{
+
+ long randint(long a, long b);
+
+ DEFINE_FUNCTOR(pythonic::random, randint);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/random/random.hpp b/contrib/python/pythran/pythran/pythonic/include/random/random.hpp
new file mode 100644
index 00000000000..84ed72880a7
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/random/random.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_RANDOM_RANDOM_HPP
+#define PYTHONIC_INCLUDE_RANDOM_RANDOM_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include <random>
+
+PYTHONIC_NS_BEGIN
+
+namespace random
+{
+
+ static std::mt19937 __random_generator;
+
+ double random();
+
+ DEFINE_FUNCTOR(pythonic::random, random);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/random/randrange.hpp b/contrib/python/pythran/pythran/pythonic/include/random/randrange.hpp
new file mode 100644
index 00000000000..08b5899189f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/random/randrange.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_RANDOM_RANDRANGE_HPP
+#define PYTHONIC_INCLUDE_RANDOM_RANDRANGE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/random/random.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace random
+{
+ long randrange(long stop);
+ long randrange(long start, long stop);
+ long randrange(long start, long stop, long step);
+
+ DEFINE_FUNCTOR(pythonic::random, randrange)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/random/sample.hpp b/contrib/python/pythran/pythran/pythonic/include/random/sample.hpp
new file mode 100644
index 00000000000..230e57b7d70
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/random/sample.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_INCLUDE_RANDOM_SAMPLE_HPP
+#define PYTHONIC_INCLUDE_RANDOM_SAMPLE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/random/random.hpp"
+
+#include "pythonic/include/types/list.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace random
+{
+ template <class Iterable>
+ types::list<typename std::iterator_traits<
+ typename std::remove_cv<typename std::remove_reference<Iterable>::type>::
+ type::iterator>::value_type>
+ sample(Iterable &&s, size_t k);
+
+ DEFINE_FUNCTOR(pythonic::random, sample);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/random/seed.hpp b/contrib/python/pythran/pythran/pythonic/include/random/seed.hpp
new file mode 100644
index 00000000000..cc41715f7ac
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/random/seed.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_INCLUDE_RANDOM_SEED_HPP
+#define PYTHONIC_INCLUDE_RANDOM_SEED_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/builtins/None.hpp"
+#include "pythonic/include/random/random.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace random
+{
+ types::none_type seed(long s);
+ types::none_type seed();
+
+ DEFINE_FUNCTOR(pythonic::random, seed);
+}
+
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/random/shuffle.hpp b/contrib/python/pythran/pythran/pythonic/include/random/shuffle.hpp
new file mode 100644
index 00000000000..797256d4bbf
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/random/shuffle.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_INCLUDE_RANDOM_SHUFFLE_HPP
+#define PYTHONIC_INCLUDE_RANDOM_SHUFFLE_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/random/random.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace random
+{
+ template <class T>
+ types::none_type shuffle(T &seq);
+ template <class T, class function>
+ types::none_type shuffle(T &seq, function &&randf);
+
+ DEFINE_FUNCTOR(pythonic::random, shuffle)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/random/uniform.hpp b/contrib/python/pythran/pythran/pythonic/include/random/uniform.hpp
new file mode 100644
index 00000000000..2559716bc7b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/random/uniform.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_RANDOM_UNIFORM_HPP
+#define PYTHONIC_INCLUDE_RANDOM_UNIFORM_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/random/random.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace random
+{
+ double uniform(double a, double b);
+
+ DEFINE_FUNCTOR(pythonic::random, uniform);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/scipy/special/binom.hpp b/contrib/python/pythran/pythran/pythonic/include/scipy/special/binom.hpp
new file mode 100644
index 00000000000..df2982d6051
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/scipy/special/binom.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_SCIPY_SPECIAL_BINOM_HPP
+#define PYTHONIC_INCLUDE_SCIPY_SPECIAL_BINOM_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+
+ namespace details
+ {
+ template <class T0, class T1>
+ double binom(T0 n, T1 k);
+ }
+
+#define NUMPY_NARY_FUNC_NAME binom
+#define NUMPY_NARY_FUNC_SYM details::binom
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/scipy/special/gamma.hpp b/contrib/python/pythran/pythran/pythonic/include/scipy/special/gamma.hpp
new file mode 100644
index 00000000000..1cf8ae271e3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/scipy/special/gamma.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_INCLUDE_SCIPY_SPECIAL_GAMMA_HPP
+#define PYTHONIC_INCLUDE_SCIPY_SPECIAL_GAMMA_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+
+#define NUMPY_NARY_FUNC_NAME gamma
+#define NUMPY_NARY_FUNC_SYM xsimd::tgamma
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/scipy/special/gammaincinv.hpp b/contrib/python/pythran/pythran/pythonic/include/scipy/special/gammaincinv.hpp
new file mode 100644
index 00000000000..89829312457
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/scipy/special/gammaincinv.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_SCIPY_SPECIAL_GAMMAINCINV_HPP
+#define PYTHONIC_INCLUDE_SCIPY_SPECIAL_GAMMAINCINV_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+ namespace details
+ {
+ template <class T0, class T1>
+ double gammaincinv(T0 x, T1 y);
+ }
+
+#define NUMPY_NARY_FUNC_NAME gammaincinv
+#define NUMPY_NARY_FUNC_SYM details::gammaincinv
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/scipy/special/gammaln.hpp b/contrib/python/pythran/pythran/pythonic/include/scipy/special/gammaln.hpp
new file mode 100644
index 00000000000..7d96d3f9e9f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/scipy/special/gammaln.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_INCLUDE_SCIPY_SPECIAL_GAMMALN_HPP
+#define PYTHONIC_INCLUDE_SCIPY_SPECIAL_GAMMALN_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+#define NUMPY_NARY_FUNC_NAME gammaln
+#define NUMPY_NARY_FUNC_SYM xsimd::lgamma
+
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/scipy/special/hankel1.hpp b/contrib/python/pythran/pythran/pythonic/include/scipy/special/hankel1.hpp
new file mode 100644
index 00000000000..70382e83447
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/scipy/special/hankel1.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_SCIPY_SPECIAL_HANKEL1_HPP
+#define PYTHONIC_INCLUDE_SCIPY_SPECIAL_HANKEL1_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/complex.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+
+ namespace details
+ {
+ template <class T0, class T1>
+ std::complex<double> hankel1(T0 x, T1 y);
+ }
+
+#define NUMPY_NARY_FUNC_NAME hankel1
+#define NUMPY_NARY_FUNC_SYM details::hankel1
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/scipy/special/hankel2.hpp b/contrib/python/pythran/pythran/pythonic/include/scipy/special/hankel2.hpp
new file mode 100644
index 00000000000..b3b6f26cf9b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/scipy/special/hankel2.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_SCIPY_SPECIAL_HANKEL2_HPP
+#define PYTHONIC_INCLUDE_SCIPY_SPECIAL_HANKEL2_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/types/complex.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+
+ namespace details
+ {
+ template <class T0, class T1>
+ std::complex<double> hankel2(T0 x, T1 y);
+ }
+
+#define NUMPY_NARY_FUNC_NAME hankel2
+#define NUMPY_NARY_FUNC_SYM details::hankel2
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/scipy/special/i0.hpp b/contrib/python/pythran/pythran/pythonic/include/scipy/special/i0.hpp
new file mode 100644
index 00000000000..a42dee09287
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/scipy/special/i0.hpp
@@ -0,0 +1,73 @@
+#ifndef PYTHONIC_INCLUDE_SCIPY_SPECIAL_I0_HPP
+#define PYTHONIC_INCLUDE_SCIPY_SPECIAL_I0_HPP
+/*
+ * Adapted from Cephes Math Library Release 2.8: June, 2000
+ * Copyright 1984, 1987, 2000 by Stephen L. Moshier
+ */
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+
+ namespace details
+ {
+ /* Chebyshev coefficients for exp(-x) I0(x)
+ * in the interval [0,8].
+ *
+ * lim(x->0){ exp(-x) I0(x) } = 1.
+ */
+ static constexpr double A[] = {
+ -4.41534164647933937950E-18, 3.33079451882223809783E-17,
+ -2.43127984654795469359E-16, 1.71539128555513303061E-15,
+ -1.16853328779934516808E-14, 7.67618549860493561688E-14,
+ -4.85644678311192946090E-13, 2.95505266312963983461E-12,
+ -1.72682629144155570723E-11, 9.67580903537323691224E-11,
+ -5.18979560163526290666E-10, 2.65982372468238665035E-9,
+ -1.30002500998624804212E-8, 6.04699502254191894932E-8,
+ -2.67079385394061173391E-7, 1.11738753912010371815E-6,
+ -4.41673835845875056359E-6, 1.64484480707288970893E-5,
+ -5.75419501008210370398E-5, 1.88502885095841655729E-4,
+ -5.76375574538582365885E-4, 1.63947561694133579842E-3,
+ -4.32430999505057594430E-3, 1.05464603945949983183E-2,
+ -2.37374148058994688156E-2, 4.93052842396707084878E-2,
+ -9.49010970480476444210E-2, 1.71620901522208775349E-1,
+ -3.04682672343198398683E-1, 6.76795274409476084995E-1};
+ /* Chebyshev coefficients for exp(-x) sqrt(x) I0(x)
+ * in the inverted interval [8,infinity].
+ *
+ * lim(x->inf){ exp(-x) sqrt(x) I0(x) } = 1/sqrt(2pi).
+ */
+ static constexpr double B[] = {
+ -7.23318048787475395456E-18, -4.83050448594418207126E-18,
+ 4.46562142029675999901E-17, 3.46122286769746109310E-17,
+ -2.82762398051658348494E-16, -3.42548561967721913462E-16,
+ 1.77256013305652638360E-15, 3.81168066935262242075E-15,
+ -9.55484669882830764870E-15, -4.15056934728722208663E-14,
+ 1.54008621752140982691E-14, 3.85277838274214270114E-13,
+ 7.18012445138366623367E-13, -1.79417853150680611778E-12,
+ -1.32158118404477131188E-11, -3.14991652796324136454E-11,
+ 1.18891471078464383424E-11, 4.94060238822496958910E-10,
+ 3.39623202570838634515E-9, 2.26666899049817806459E-8,
+ 2.04891858946906374183E-7, 2.89137052083475648297E-6,
+ 6.88975834691682398426E-5, 3.36911647825569408990E-3,
+ 8.04490411014108831608E-1};
+
+ template <class T>
+ double i0(T x);
+ }
+
+#define NUMPY_NARY_FUNC_NAME i0
+#define NUMPY_NARY_FUNC_SYM details::i0
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/scipy/special/i0e.hpp b/contrib/python/pythran/pythran/pythonic/include/scipy/special/i0e.hpp
new file mode 100644
index 00000000000..dbb47435efb
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/scipy/special/i0e.hpp
@@ -0,0 +1,30 @@
+#ifndef PYTHONIC_INCLUDE_SCIPY_SPECIAL_I0E_HPP
+#define PYTHONIC_INCLUDE_SCIPY_SPECIAL_I0E_HPP
+/*
+ * Adapted from Cephes Math Library Release 2.8: June, 2000
+ * Copyright 1984, 1987, 2000 by Stephen L. Moshier
+ */
+
+#include "pythonic/include/scipy/special/i0.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+
+ namespace details
+ {
+ template <class T>
+ double i0e(T x);
+ }
+
+#define NUMPY_NARY_FUNC_NAME i0e
+#define NUMPY_NARY_FUNC_SYM details::i0e
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/scipy/special/iv.hpp b/contrib/python/pythran/pythran/pythonic/include/scipy/special/iv.hpp
new file mode 100644
index 00000000000..0c4b0f846c6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/scipy/special/iv.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_SCIPY_SPECIAL_IV_HPP
+#define PYTHONIC_INCLUDE_SCIPY_SPECIAL_IV_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+
+ namespace details
+ {
+ template <class T0, class T1>
+ double iv(T0 x, T1 y);
+ }
+
+#define NUMPY_NARY_FUNC_NAME iv
+#define NUMPY_NARY_FUNC_SYM details::iv
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/scipy/special/ivp.hpp b/contrib/python/pythran/pythran/pythonic/include/scipy/special/ivp.hpp
new file mode 100644
index 00000000000..f9f03e6de5c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/scipy/special/ivp.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_SCIPY_SPECIAL_IVP_HPP
+#define PYTHONIC_INCLUDE_SCIPY_SPECIAL_IVP_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+
+ namespace details
+ {
+ template <class T0, class T1>
+ double ivp(T0 x, T1 y);
+ }
+
+#define NUMPY_NARY_FUNC_NAME ivp
+#define NUMPY_NARY_FUNC_SYM details::ivp
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/scipy/special/jv.hpp b/contrib/python/pythran/pythran/pythonic/include/scipy/special/jv.hpp
new file mode 100644
index 00000000000..97440d85ebf
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/scipy/special/jv.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_SCIPY_SPECIAL_JV_HPP
+#define PYTHONIC_INCLUDE_SCIPY_SPECIAL_JV_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+
+ namespace details
+ {
+ template <class T0, class T1>
+ double jv(T0 x, T1 y);
+ }
+
+#define NUMPY_NARY_FUNC_NAME jv
+#define NUMPY_NARY_FUNC_SYM details::jv
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/scipy/special/jvp.hpp b/contrib/python/pythran/pythran/pythonic/include/scipy/special/jvp.hpp
new file mode 100644
index 00000000000..2eea0b4ebf8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/scipy/special/jvp.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_SCIPY_SPECIAL_JVP_HPP
+#define PYTHONIC_INCLUDE_SCIPY_SPECIAL_JVP_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+
+ namespace details
+ {
+ template <class T0, class T1>
+ double jvp(T0 x, T1 y);
+ }
+
+#define NUMPY_NARY_FUNC_NAME jvp
+#define NUMPY_NARY_FUNC_SYM details::jvp
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/scipy/special/kv.hpp b/contrib/python/pythran/pythran/pythonic/include/scipy/special/kv.hpp
new file mode 100644
index 00000000000..b8b2bff86ce
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/scipy/special/kv.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_SCIPY_SPECIAL_KV_HPP
+#define PYTHONIC_INCLUDE_SCIPY_SPECIAL_KV_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+
+ namespace details
+ {
+ template <class T0, class T1>
+ double kv(T0 x, T1 y);
+ }
+
+#define NUMPY_NARY_FUNC_NAME kv
+#define NUMPY_NARY_FUNC_SYM details::kv
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/scipy/special/kvp.hpp b/contrib/python/pythran/pythran/pythonic/include/scipy/special/kvp.hpp
new file mode 100644
index 00000000000..37271762926
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/scipy/special/kvp.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_SCIPY_SPECIAL_KVP_HPP
+#define PYTHONIC_INCLUDE_SCIPY_SPECIAL_KVP_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+
+ namespace details
+ {
+ template <class T0, class T1>
+ double kvp(T0 x, T1 y);
+ }
+
+#define NUMPY_NARY_FUNC_NAME kvp
+#define NUMPY_NARY_FUNC_SYM details::kvp
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/scipy/special/ndtr.hpp b/contrib/python/pythran/pythran/pythonic/include/scipy/special/ndtr.hpp
new file mode 100644
index 00000000000..e0c3d4ca411
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/scipy/special/ndtr.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_SCIPY_SPECIAL_NDTR_HPP
+#define PYTHONIC_INCLUDE_SCIPY_SPECIAL_NDTR_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+ namespace details
+ {
+ template <class T>
+ double ndtr(T x);
+ }
+
+#define NUMPY_NARY_FUNC_NAME ndtr
+#define NUMPY_NARY_FUNC_SYM details::ndtr
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/scipy/special/ndtri.hpp b/contrib/python/pythran/pythran/pythonic/include/scipy/special/ndtri.hpp
new file mode 100644
index 00000000000..17e70609ec7
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/scipy/special/ndtri.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_INCLUDE_SCIPY_SPECIAL_NDTRI_HPP
+#define PYTHONIC_INCLUDE_SCIPY_SPECIAL_NDTRI_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+ namespace details
+ {
+ template <class T>
+ double ndtri(T x);
+ }
+
+#define NUMPY_NARY_FUNC_NAME ndtri
+#define NUMPY_NARY_FUNC_SYM details::ndtri
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/scipy/special/spherical_jn.hpp b/contrib/python/pythran/pythran/pythonic/include/scipy/special/spherical_jn.hpp
new file mode 100644
index 00000000000..eba7a55b080
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/scipy/special/spherical_jn.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_SCIPY_SPECIAL_SPHERICAL_JN_HPP
+#define PYTHONIC_INCLUDE_SCIPY_SPECIAL_SPHERICAL_JN_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+
+ namespace details
+ {
+ template <class T0, class T1>
+ double spherical_jn(T0 v, T1 x, bool derivative = false);
+ }
+
+#define NUMPY_NARY_FUNC_NAME spherical_jn
+#define NUMPY_NARY_FUNC_SYM details::spherical_jn
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/scipy/special/spherical_yn.hpp b/contrib/python/pythran/pythran/pythonic/include/scipy/special/spherical_yn.hpp
new file mode 100644
index 00000000000..211a8e1d2ce
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/scipy/special/spherical_yn.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_SCIPY_SPECIAL_SPHERICAL_YN_HPP
+#define PYTHONIC_INCLUDE_SCIPY_SPECIAL_SPHERICAL_YN_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+
+ namespace details
+ {
+ template <class T0, class T1>
+ double spherical_yn(T0 v, T1 x, bool derivative = false);
+ }
+
+#define NUMPY_NARY_FUNC_NAME spherical_yn
+#define NUMPY_NARY_FUNC_SYM details::spherical_yn
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/scipy/special/yv.hpp b/contrib/python/pythran/pythran/pythonic/include/scipy/special/yv.hpp
new file mode 100644
index 00000000000..c8936a8e1e8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/scipy/special/yv.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_SCIPY_SPECIAL_YV_HPP
+#define PYTHONIC_INCLUDE_SCIPY_SPECIAL_YV_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+
+ namespace details
+ {
+ template <class T0, class T1>
+ double yv(T0 x, T1 y);
+ }
+
+#define NUMPY_NARY_FUNC_NAME yv
+#define NUMPY_NARY_FUNC_SYM details::yv
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/scipy/special/yvp.hpp b/contrib/python/pythran/pythran/pythonic/include/scipy/special/yvp.hpp
new file mode 100644
index 00000000000..53aba998de7
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/scipy/special/yvp.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_INCLUDE_SCIPY_SPECIAL_YVP_HPP
+#define PYTHONIC_INCLUDE_SCIPY_SPECIAL_YVP_HPP
+
+#include "pythonic/include/types/ndarray.hpp"
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+
+ namespace details
+ {
+ template <class T0, class T1>
+ double yvp(T0 x, T1 y);
+ }
+
+#define NUMPY_NARY_FUNC_NAME yvp
+#define NUMPY_NARY_FUNC_SYM details::yvp
+#include "pythonic/include/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/string/ascii_letters.hpp b/contrib/python/pythran/pythran/pythonic/include/string/ascii_letters.hpp
new file mode 100644
index 00000000000..cbfefa9d67f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/string/ascii_letters.hpp
@@ -0,0 +1,15 @@
+#ifndef PYTHONIC_INCLUDE_STRING_ASCII_LETTERS_HPP
+#define PYTHONIC_INCLUDE_STRING_ASCII_LETTERS_HPP
+
+#include "pythonic/types/str.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace string
+{
+ static types::str const
+ ascii_letters("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/string/ascii_lowercase.hpp b/contrib/python/pythran/pythran/pythonic/include/string/ascii_lowercase.hpp
new file mode 100644
index 00000000000..63a016b6dde
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/string/ascii_lowercase.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_STRING_ASCII_LOWERCASE_HPP
+#define PYTHONIC_INCLUDE_STRING_ASCII_LOWERCASE_HPP
+
+#include "pythonic/types/str.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace string
+{
+ static types::str const ascii_lowercase("abcdefghijklmnopqrstuvwxyz");
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/string/ascii_uppercase.hpp b/contrib/python/pythran/pythran/pythonic/include/string/ascii_uppercase.hpp
new file mode 100644
index 00000000000..75deb246b4e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/string/ascii_uppercase.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_STRING_ASCII_UPPERCASE_HPP
+#define PYTHONIC_INCLUDE_STRING_ASCII_UPPERCASE_HPP
+
+#include "pythonic/types/str.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace string
+{
+ static types::str const ascii_uppercase("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/string/digits.hpp b/contrib/python/pythran/pythran/pythonic/include/string/digits.hpp
new file mode 100644
index 00000000000..89627084505
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/string/digits.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_STRING_DIGITS_HPP
+#define PYTHONIC_INCLUDE_STRING_DIGITS_HPP
+
+#include "pythonic/types/str.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace string
+{
+ static types::str const digits("0123456789");
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/string/find.hpp b/contrib/python/pythran/pythran/pythonic/include/string/find.hpp
new file mode 100644
index 00000000000..9e26442ff58
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/string/find.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_INCLUDE_STRING_FIND_HPP
+#define PYTHONIC_INCLUDE_STRING_FIND_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/str.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace string
+{
+
+ template <class T>
+ long find(types::str const &s, T &&val);
+
+ DEFINE_FUNCTOR(pythonic::string, find);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/string/hexdigits.hpp b/contrib/python/pythran/pythran/pythonic/include/string/hexdigits.hpp
new file mode 100644
index 00000000000..b038b52e1cb
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/string/hexdigits.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_STRING_HEXDIGITS_HPP
+#define PYTHONIC_INCLUDE_STRING_HEXDIGITS_HPP
+
+#include "pythonic/types/str.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace string
+{
+ static types::str const hexdigits("0123456789abcdefABCDEF");
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/string/octdigits.hpp b/contrib/python/pythran/pythran/pythonic/include/string/octdigits.hpp
new file mode 100644
index 00000000000..68ebb2d45db
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/string/octdigits.hpp
@@ -0,0 +1,14 @@
+#ifndef PYTHONIC_INCLUDE_STRING_OCTDIGITS_HPP
+#define PYTHONIC_INCLUDE_STRING_OCTDIGITS_HPP
+
+#include "pythonic/types/str.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace string
+{
+ static types::str const octdigits("01234567");
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/time/sleep.hpp b/contrib/python/pythran/pythran/pythonic/include/time/sleep.hpp
new file mode 100644
index 00000000000..9634aa2979e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/time/sleep.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_TIME_SLEEP_HPP
+#define PYTHONIC_INCLUDE_TIME_SLEEP_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace time
+{
+ types::none_type sleep(double const value);
+
+ DEFINE_FUNCTOR(pythonic::time, sleep)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/time/time.hpp b/contrib/python/pythran/pythran/pythonic/include/time/time.hpp
new file mode 100644
index 00000000000..6ee19ae75a8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/time/time.hpp
@@ -0,0 +1,17 @@
+#ifndef PYTHONIC_INCLUDE_TIME_TIME_HPP
+#define PYTHONIC_INCLUDE_TIME_TIME_HPP
+
+#include "pythonic/include/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace time
+{
+
+ double time();
+
+ DEFINE_FUNCTOR(pythonic::time, time)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/types/cfun.hpp b/contrib/python/pythran/pythran/pythonic/include/types/cfun.hpp
new file mode 100644
index 00000000000..2dc6d48ed41
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/types/cfun.hpp
@@ -0,0 +1,46 @@
+#ifndef PYTHONIC_INCLUDE_TYPES_CFUN_HPP
+#define PYTHONIC_INCLUDE_TYPES_CFUN_HPP
+
+PYTHONIC_NS_BEGIN
+
+namespace types
+{
+
+ template <class T>
+ struct cfun;
+
+ template <class ReturnType, class... ArgsType>
+ struct cfun<ReturnType(ArgsType...)> {
+
+ using callable = void;
+
+ cfun(ReturnType (*fun)(ArgsType...));
+
+ ReturnType (*ptr)(ArgsType...);
+
+ ReturnType operator()(ArgsType... args) const;
+ };
+}
+PYTHONIC_NS_END
+
+#ifdef ENABLE_PYTHON_MODULE
+
+#include "pythonic/python/core.hpp"
+
+PYTHONIC_NS_BEGIN
+
+template <class R, class... Args>
+struct to_python<types::cfun<R(Args...)>> {
+ static PyObject *convert(types::cfun<R(Args...)> const &v);
+};
+
+template <class R, class... Args>
+struct from_python<types::cfun<R(Args...)>> {
+ static bool is_convertible(PyObject *obj);
+ static types::cfun<R(Args...)> convert(PyObject *obj);
+};
+PYTHONIC_NS_END
+
+#endif
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/types/clongdouble.hpp b/contrib/python/pythran/pythran/pythonic/include/types/clongdouble.hpp
new file mode 100644
index 00000000000..dd666a52f51
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/types/clongdouble.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_INCLUDE_TYPES_CLONGDOUBLE_HPP
+#define PYTHONIC_INCLUDE_TYPES_CLONGDOUBLE_HPP
+
+#include "pythonic/include/types/complex.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/types/complex256.hpp b/contrib/python/pythran/pythran/pythonic/include/types/complex256.hpp
new file mode 100644
index 00000000000..3ecf46b3d59
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/types/complex256.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_INCLUDE_TYPES_COMPLEX256_HPP
+#define PYTHONIC_INCLUDE_TYPES_COMPLEX256_HPP
+
+#include "pythonic/include/types/complex.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/types/complex64.hpp b/contrib/python/pythran/pythran/pythonic/include/types/complex64.hpp
new file mode 100644
index 00000000000..1f067b51e83
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/types/complex64.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_INCLUDE_TYPES_COMPLEX64_HPP
+#define PYTHONIC_INCLUDE_TYPES_COMPLEX64_HPP
+
+#include "pythonic/include/types/complex.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/types/file.hpp b/contrib/python/pythran/pythran/pythonic/include/types/file.hpp
new file mode 100644
index 00000000000..8781adb250a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/types/file.hpp
@@ -0,0 +1,131 @@
+#ifndef PYTHONIC_INCLUDE_TYPES_FILE_HPP
+#define PYTHONIC_INCLUDE_TYPES_FILE_HPP
+
+#include "pythonic/include/types/assignable.hpp"
+#include "pythonic/include/utils/shared_ref.hpp"
+#include "pythonic/include/types/str.hpp"
+#include "pythonic/include/types/list.hpp"
+#include "pythonic/include/types/NoneType.hpp"
+#include "pythonic/include/types/attr.hpp"
+
+#include <fstream>
+#include <iterator>
+#include <string>
+
+PYTHONIC_NS_BEGIN
+
+namespace types
+{
+ class file;
+
+ struct file_iterator
+ : std::iterator<std::forward_iterator_tag, types::str, ptrdiff_t,
+ types::str *, types::str /* no ref */> {
+ private:
+ file *f;
+ mutable bool set;
+ mutable types::str curr;
+ long position;
+
+ public:
+ using value_type = types::str;
+
+ file_iterator(file &ref);
+ file_iterator();
+ bool operator==(file_iterator const &f2) const;
+ bool operator!=(file_iterator const &f2) const;
+ bool operator<(file_iterator const &f2) const;
+ file_iterator &operator++();
+ types::str operator*() const;
+ };
+
+ struct _file {
+ FILE *f;
+ _file();
+ _file(types::str const &filename, types::str const &strmode = "r");
+ FILE *operator*() const;
+ ~_file();
+ };
+
+ class file : public file_iterator
+ {
+
+ private:
+ using container_type = _file;
+ utils::shared_ref<container_type> data;
+ bool is_open;
+ types::str mode, name, newlines;
+
+ public:
+ // Types
+ using iterator = file_iterator;
+ using value_type = types::str;
+
+ // Constructors
+ file();
+ file(types::str const &filename, types::str const &strmode = "r");
+
+ // Iterators
+ iterator begin();
+ iterator end();
+
+ // Modifiers
+ void open(types::str const &filename, types::str const &strmode);
+
+ void close();
+
+ bool closed() const;
+
+ types::str const &getmode() const;
+
+ types::str const &getname() const;
+
+ types::str const &getnewlines() const;
+
+ bool eof();
+
+ void flush();
+
+ long fileno() const;
+
+ bool isatty() const;
+
+ types::str read(long size = -1);
+
+ types::str readline(long size = std::numeric_limits<long>::max());
+
+ types::list<types::str> readlines(long sizehint = -1);
+
+ void seek(long offset, long whence = SEEK_SET);
+
+ long tell() const;
+
+ void truncate(long size = -1);
+
+ long write(types::str const &str);
+
+ template <class T>
+ void writelines(T const &seq);
+ };
+}
+PYTHONIC_NS_END
+
+/* pythran attribute system { */
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+ bool getattr(types::attr::CLOSED, types::file const &f);
+
+ types::str const &getattr(types::attr::MODE, types::file const &f);
+
+ types::str const &getattr(types::attr::NAME, types::file const &f);
+
+ // Python seems to always return none... Doing the same.
+ types::none_type getattr(types::attr::NEWLINES, types::file const &f);
+}
+PYTHONIC_NS_END
+
+/* } */
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/types/finfo.hpp b/contrib/python/pythran/pythran/pythonic/include/types/finfo.hpp
new file mode 100644
index 00000000000..f5af81c04b1
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/types/finfo.hpp
@@ -0,0 +1,34 @@
+#ifndef PYTHONIC_INCLUDE_TYPES_FINFO_HPP
+#define PYTHONIC_INCLUDE_TYPES_FINFO_HPP
+
+#include "pythonic/include/types/attr.hpp"
+
+#include <limits>
+
+PYTHONIC_NS_BEGIN
+
+namespace types
+{
+ template <class T>
+ struct finfo {
+ T eps() const;
+ };
+
+ template <class T>
+ struct finfo<std::complex<T>> {
+ T eps() const;
+ };
+}
+PYTHONIC_NS_END
+
+/* pythran attribute system { */
+PYTHONIC_NS_BEGIN
+namespace builtins
+{
+ template <class T>
+ auto getattr(types::attr::EPS, pythonic::types::finfo<T> const &f)
+ -> decltype(f.eps());
+}
+PYTHONIC_NS_END
+/* } */
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/types/float128.hpp b/contrib/python/pythran/pythran/pythonic/include/types/float128.hpp
new file mode 100644
index 00000000000..f38b739a459
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/types/float128.hpp
@@ -0,0 +1,4 @@
+#ifndef PYTHONIC_INCLUDE_TYPES_FLOAT128_HPP
+#define PYTHONIC_INCLUDE_TYPES_FLOAT128_HPP
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/types/immediate.hpp b/contrib/python/pythran/pythran/pythonic/include/types/immediate.hpp
new file mode 100644
index 00000000000..7e7bf3e075c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/types/immediate.hpp
@@ -0,0 +1,33 @@
+#ifndef PYTHONIC_INCLUDE_TYPES_IMMEDIATE_HPP
+#define PYTHONIC_INCLUDE_TYPES_IMMEDIATE_HPP
+
+PYTHONIC_NS_BEGIN
+
+namespace types
+{
+
+ template <class T, T Val>
+ struct immediate {
+ immediate() = default;
+ immediate(immediate const &) = default;
+ immediate(immediate &&) = default;
+
+ operator T() const
+ {
+ return Val;
+ }
+
+ template <class U, U Wal,
+ class _ = typename std::enable_if<Val == (T)Wal, void>::type>
+ immediate(std::integral_constant<U, Wal>)
+ {
+ }
+ };
+
+ using true_immediate = immediate<bool, true>;
+ using false_immediate = immediate<bool, false>;
+}
+
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/types/int16.hpp b/contrib/python/pythran/pythran/pythonic/include/types/int16.hpp
new file mode 100644
index 00000000000..bba44a96db8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/types/int16.hpp
@@ -0,0 +1,4 @@
+#ifndef PYTHONIC_INCLUDE_TYPES_INT16_HPP
+#define PYTHONIC_INCLUDE_TYPES_INT16_HPP
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/types/intc.hpp b/contrib/python/pythran/pythran/pythonic/include/types/intc.hpp
new file mode 100644
index 00000000000..d175eb01a0f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/types/intc.hpp
@@ -0,0 +1,4 @@
+#ifndef PYTHONIC_INCLUDE_TYPES_INTC_HPP
+#define PYTHONIC_INCLUDE_TYPES_INTC_HPP
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/types/intp.hpp b/contrib/python/pythran/pythran/pythonic/include/types/intp.hpp
new file mode 100644
index 00000000000..0e64dbc37a4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/types/intp.hpp
@@ -0,0 +1,4 @@
+#ifndef PYTHONIC_INCLUDE_TYPES_INTP_HPP
+#define PYTHONIC_INCLUDE_TYPES_INTP_HPP
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/types/longdouble.hpp b/contrib/python/pythran/pythran/pythonic/include/types/longdouble.hpp
new file mode 100644
index 00000000000..1ee2fca96c8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/types/longdouble.hpp
@@ -0,0 +1,4 @@
+#ifndef PYTHONIC_INCLUDE_TYPES_LONGDOUBLE_HPP
+#define PYTHONIC_INCLUDE_TYPES_LONGDOUBLE_HPP
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/types/numpy_ufunc.hpp b/contrib/python/pythran/pythran/pythonic/include/types/numpy_ufunc.hpp
new file mode 100644
index 00000000000..6c97ea92c1c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/types/numpy_ufunc.hpp
@@ -0,0 +1,39 @@
+#ifndef PYTHONIC_INCLUDE_TYPES_NUMPY_UFUNC_HPP
+#define PYTHONIC_INCLUDE_TYPES_NUMPY_UFUNC_HPP
+
+#include "numpy/ufuncobject.h"
+
+PYTHONIC_NS_BEGIN
+
+namespace types
+{
+ namespace detail
+ {
+ template <class F, typename ResType, typename... ArgTypes, size_t... Is>
+ void ufunc_wrapper(char *output, char **inputs, npy_intp n,
+ npy_intp output_step, const npy_intp *inputs_steps,
+ utils::index_sequence<Is...>)
+ {
+ for (npy_intp i = 0; i < n; ++i) {
+ *(ResType *)output =
+ F{}(*(typename std::tuple_element<Is, std::tuple<ArgTypes...>>::type
+ *)(inputs[Is])...);
+ output += output_step;
+ (void)std::initializer_list<int>{
+ ((inputs[Is] += inputs_steps[Is]), 0)...};
+ }
+ }
+ } // namespace detail
+ template <class F, typename ResType, typename... ArgTypes>
+ void ufunc_wrapper(char **args, npy_intp const *dimensions,
+ npy_intp const *steps, void * /*extra*/)
+ {
+ npy_intp output_step = steps[sizeof...(ArgTypes)];
+ return detail::ufunc_wrapper<F, ResType, ArgTypes...>(
+ args[sizeof...(ArgTypes)], args, dimensions[0], output_step, steps,
+ utils::make_index_sequence<sizeof...(ArgTypes)>());
+ }
+} // namespace types
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/types/static_if.hpp b/contrib/python/pythran/pythran/pythonic/include/types/static_if.hpp
new file mode 100644
index 00000000000..86e4b6c9461
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/types/static_if.hpp
@@ -0,0 +1,301 @@
+#ifndef PYTHONIC_INCLUDE_TYPES_STATIC_IF_HPP
+#define PYTHONIC_INCLUDE_TYPES_STATIC_IF_HPP
+
+#include <tuple>
+
+PYTHONIC_NS_BEGIN
+
+namespace types
+{
+ template <class T>
+ struct StaticIfReturn {
+ T arg;
+ };
+
+ template <class T>
+ struct StaticIfNoReturn {
+ T arg;
+ StaticIfNoReturn() = default;
+ StaticIfNoReturn(T const &arg) : arg(arg)
+ {
+ }
+ long get(std::integral_constant<size_t, 0>)
+ {
+ return 0;
+ }
+ StaticIfNoReturn &get(std::integral_constant<size_t, 1>)
+ {
+ return *this;
+ }
+ T &get(std::integral_constant<size_t, 2>)
+ {
+ return arg;
+ }
+
+ template <class OT>
+ operator OT() const
+ {
+ return OT();
+ }
+ };
+
+ template <class T>
+ struct StaticIfBreak {
+ T arg;
+ StaticIfBreak() = default;
+ StaticIfBreak(T const &arg) : arg(arg)
+ {
+ }
+ long get(std::integral_constant<size_t, 0>)
+ {
+ return 1;
+ }
+ T &get(std::integral_constant<size_t, 1>)
+ {
+ return arg;
+ }
+ T &get(std::integral_constant<size_t, 2>)
+ {
+ return arg;
+ }
+
+ template <class OT>
+ operator OT() const
+ {
+ return OT();
+ }
+ };
+
+ template <class T>
+ struct StaticIfCont {
+ T arg;
+ StaticIfCont() = default;
+ StaticIfCont(T const &arg) : arg(arg)
+ {
+ }
+ long get(std::integral_constant<size_t, 0>)
+ {
+ return 2;
+ }
+ StaticIfCont &get(std::integral_constant<size_t, 1>)
+ {
+ return *this;
+ }
+ T &get(std::integral_constant<size_t, 2>)
+ {
+ return arg;
+ }
+
+ template <class OT>
+ operator OT() const
+ {
+ return OT();
+ }
+ };
+
+ template <class T0, class T1>
+ struct StaticIfReturnHolder {
+ std::tuple<int, T0, T1> args;
+
+ StaticIfReturnHolder() : args(0, T0(), T1())
+ {
+ }
+ StaticIfReturnHolder(StaticIfReturnHolder<T0, T1> const &) = default;
+
+ template <class Tp0, class Tp1>
+ StaticIfReturnHolder(StaticIfReturnHolder<Tp0, Tp1> const &other)
+ : args(other.args)
+ {
+ }
+
+ template <class Tp0>
+ StaticIfReturnHolder(StaticIfReturn<Tp0> const &arg)
+ : args(1, arg.arg, T1())
+ {
+ }
+ StaticIfReturnHolder(StaticIfNoReturn<T1> const &arg)
+ : args(0, T0(), arg.arg)
+ {
+ }
+ StaticIfReturnHolder(StaticIfBreak<T1> const &arg) : args(2, T0(), arg.arg)
+ {
+ }
+ StaticIfReturnHolder(StaticIfCont<T1> const &arg) : args(3, T0(), arg.arg)
+ {
+ }
+ };
+}
+
+PYTHONIC_NS_END
+
+namespace std
+{
+ template <size_t I, class T0, class T1>
+ struct tuple_element<I, pythonic::types::StaticIfReturnHolder<T0, T1>> {
+ using type = typename std::conditional<
+ I == 0, bool, typename std::conditional<I == 1, T0, T1>::type>::type;
+ };
+ template <size_t I, class T0, class T1>
+ auto get(pythonic::types::StaticIfReturnHolder<T0, T1> &t)
+ -> decltype(std::get<I>(t.args))
+ {
+ return std::get<I>(t.args);
+ }
+
+ template <size_t I, class T>
+ struct tuple_element<I, pythonic::types::StaticIfNoReturn<T>> {
+ using type =
+ decltype(std::declval<pythonic::types::StaticIfNoReturn<T>>().get(
+ std::integral_constant<size_t, I>{}));
+ };
+
+ template <size_t I, class T>
+ auto get(pythonic::types::StaticIfNoReturn<T> &t)
+ -> decltype(t.get(std::integral_constant<size_t, I>{}))
+ {
+ return t.get(std::integral_constant<size_t, I>{});
+ }
+
+ template <size_t I, class T>
+ struct tuple_element<I, pythonic::types::StaticIfBreak<T>> {
+ using type = decltype(std::declval<pythonic::types::StaticIfBreak<T>>().get(
+ std::integral_constant<size_t, I>{}));
+ };
+
+ template <size_t I, class T>
+ auto get(pythonic::types::StaticIfBreak<T> &t)
+ -> decltype(t.get(std::integral_constant<size_t, I>{}))
+ {
+ return t.get(std::integral_constant<size_t, I>{});
+ }
+
+ template <size_t I, class T>
+ struct tuple_element<I, pythonic::types::StaticIfCont<T>> {
+ using type = decltype(std::declval<pythonic::types::StaticIfCont<T>>().get(
+ std::integral_constant<size_t, I>{}));
+ };
+
+ template <size_t I, class T>
+ auto get(pythonic::types::StaticIfCont<T> &t)
+ -> decltype(t.get(std::integral_constant<size_t, I>{}))
+ {
+ return t.get(std::integral_constant<size_t, I>{});
+ }
+}
+
+/* type inference stuff { */
+#include "pythonic/include/types/combined.hpp"
+
+template <class T0, class T1>
+struct __combined<pythonic::types::StaticIfReturn<T0>,
+ pythonic::types::StaticIfNoReturn<T1>> {
+ using type = pythonic::types::StaticIfReturnHolder<T0, T1>;
+};
+template <class T0, class T1>
+struct __combined<pythonic::types::StaticIfReturn<T0>,
+ pythonic::types::StaticIfBreak<T1>> {
+ using type = pythonic::types::StaticIfReturnHolder<T0, T1>;
+};
+template <class T0, class T1>
+struct __combined<pythonic::types::StaticIfReturn<T0>,
+ pythonic::types::StaticIfCont<T1>> {
+ using type = pythonic::types::StaticIfReturnHolder<T0, T1>;
+};
+
+template <class T0, class T1>
+struct __combined<pythonic::types::StaticIfNoReturn<T1>,
+ pythonic::types::StaticIfReturn<T0>> {
+ using type = pythonic::types::StaticIfReturnHolder<T0, T1>;
+};
+
+template <class T0>
+struct __combined<pythonic::types::StaticIfNoReturn<T0> &,
+ pythonic::types::none_type> {
+ using type = pythonic::types::none_type;
+};
+template <class T0>
+struct __combined<pythonic::types::StaticIfNoReturn<T0>,
+ pythonic::types::none_type> {
+ using type = pythonic::types::none_type;
+};
+template <class T0>
+struct __combined<pythonic::types::none_type,
+ pythonic::types::StaticIfNoReturn<T0>> {
+ using type = pythonic::types::none_type;
+};
+template <class T0, class T1>
+struct __combined<pythonic::types::StaticIfBreak<T1>,
+ pythonic::types::StaticIfReturn<T0>> {
+ using type = pythonic::types::StaticIfReturnHolder<T0, T1>;
+};
+template <class T0, class T1>
+struct __combined<pythonic::types::StaticIfCont<T1>,
+ pythonic::types::StaticIfReturn<T0>> {
+ using type = pythonic::types::StaticIfReturnHolder<T0, T1>;
+};
+
+template <class T0, class T1, class T2, class T3>
+struct __combined<pythonic::types::StaticIfReturnHolder<T0, T1>,
+ pythonic::types::StaticIfReturnHolder<T2, T3>> {
+ using type =
+ pythonic::types::StaticIfReturnHolder<typename __combined<T0, T2>::type,
+ typename __combined<T1, T3>::type>;
+};
+template <class T0, class T1, class T2>
+struct __combined<pythonic::types::StaticIfReturnHolder<T0, T1>,
+ pythonic::types::StaticIfCont<T2>> {
+ using type =
+ pythonic::types::StaticIfReturnHolder<typename __combined<T0, T2>::type,
+ T1>;
+};
+template <class T0, class T1, class T2>
+struct __combined<pythonic::types::StaticIfReturnHolder<T0, T1>,
+ pythonic::types::StaticIfBreak<T2>> {
+ using type =
+ pythonic::types::StaticIfReturnHolder<typename __combined<T0, T2>::type,
+ T1>;
+};
+template <class T0, class T1, class T2>
+struct __combined<pythonic::types::StaticIfReturnHolder<T0, T1>,
+ pythonic::types::StaticIfReturn<T2>> {
+ using type =
+ pythonic::types::StaticIfReturnHolder<typename __combined<T0, T2>::type,
+ T1>;
+};
+
+template <class T0, class T1, class T2>
+struct __combined<pythonic::types::StaticIfCont<T2>,
+ pythonic::types::StaticIfReturnHolder<T0, T1>> {
+ using type =
+ pythonic::types::StaticIfReturnHolder<typename __combined<T0, T2>::type,
+ T1>;
+};
+
+template <class T0, class T1, class T2>
+struct __combined<pythonic::types::StaticIfBreak<T2>,
+ pythonic::types::StaticIfReturnHolder<T0, T1>> {
+ using type =
+ pythonic::types::StaticIfReturnHolder<typename __combined<T0, T2>::type,
+ T1>;
+};
+
+template <class T0, class T1, class T2>
+struct __combined<pythonic::types::StaticIfReturn<T2>,
+ pythonic::types::StaticIfReturnHolder<T0, T1>> {
+ using type =
+ pythonic::types::StaticIfReturnHolder<typename __combined<T0, T2>::type,
+ T1>;
+};
+
+template <class T0, class T1>
+struct __combined<T0, pythonic::types::StaticIfNoReturn<T1>> {
+ using type = T0;
+};
+
+template <class T0, class T1>
+struct __combined<pythonic::types::StaticIfNoReturn<T1>, T0> {
+ using type = T0;
+};
+
+/* } */
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/types/uint16.hpp b/contrib/python/pythran/pythran/pythonic/include/types/uint16.hpp
new file mode 100644
index 00000000000..dd1970ab678
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/types/uint16.hpp
@@ -0,0 +1,4 @@
+#ifndef PYTHONIC_INCLUDE_TYPES_UINT16_HPP
+#define PYTHONIC_INCLUDE_TYPES_UINT16_HPP
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/types/uint32.hpp b/contrib/python/pythran/pythran/pythonic/include/types/uint32.hpp
new file mode 100644
index 00000000000..60a58952fe0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/types/uint32.hpp
@@ -0,0 +1,4 @@
+#ifndef PYTHONIC_INCLUDE_TYPES_UINT32_HPP
+#define PYTHONIC_INCLUDE_TYPES_UINT32_HPP
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/types/uint64.hpp b/contrib/python/pythran/pythran/pythonic/include/types/uint64.hpp
new file mode 100644
index 00000000000..9f1aaf71199
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/types/uint64.hpp
@@ -0,0 +1,4 @@
+#ifndef PYTHONIC_INCLUDE_TYPES_UINT64_HPP
+#define PYTHONIC_INCLUDE_TYPES_UINT64_HPP
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/types/uint8.hpp b/contrib/python/pythran/pythran/pythonic/include/types/uint8.hpp
new file mode 100644
index 00000000000..3dd802cbaeb
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/types/uint8.hpp
@@ -0,0 +1,4 @@
+#ifndef PYTHONIC_INCLUDE_TYPES_UINT8_HPP
+#define PYTHONIC_INCLUDE_TYPES_UINT8_HPP
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/types/uintc.hpp b/contrib/python/pythran/pythran/pythonic/include/types/uintc.hpp
new file mode 100644
index 00000000000..96247f6e4ec
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/types/uintc.hpp
@@ -0,0 +1,4 @@
+#ifndef PYTHONIC_INCLUDE_TYPES_UINTC_HPP
+#define PYTHONIC_INCLUDE_TYPES_UINTC_HPP
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/types/uintp.hpp b/contrib/python/pythran/pythran/pythonic/include/types/uintp.hpp
new file mode 100644
index 00000000000..70335484a93
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/types/uintp.hpp
@@ -0,0 +1,4 @@
+#ifndef PYTHONIC_INCLUDE_TYPES_UINTP_HPP
+#define PYTHONIC_INCLUDE_TYPES_UINTP_HPP
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/include/utils/tags.hpp b/contrib/python/pythran/pythran/pythonic/include/utils/tags.hpp
new file mode 100644
index 00000000000..00687a6b181
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/include/utils/tags.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_INCLUDE_UTILS_TAGS_HPP
+#define PYTHONIC_INCLUDE_UTILS_TAGS_HPP
+
+#include "pythonic/include/types/traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace purity
+{
+ struct unknown_tag {
+ };
+
+ struct pure_tag {
+ };
+}
+
+template <class T>
+struct purity_of {
+ using type =
+ typename std::conditional<types::is_pure<T>::value, purity::pure_tag,
+ purity::unknown_tag>::type;
+};
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/close.hpp b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/close.hpp
new file mode 100644
index 00000000000..a6baf27edbc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/close.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_IO__IO_TEXTIOWRAPPER_CLOSE_HPP
+#define PYTHONIC_IO__IO_TEXTIOWRAPPER_CLOSE_HPP
+
+#include "pythonic/include/io/_io/TextIOWrapper/close.hpp"
+#include "pythonic/builtins/file/close.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/fileno.hpp b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/fileno.hpp
new file mode 100644
index 00000000000..8df4ed963e2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/fileno.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_IO__IO_TEXTIOWRAPPER_FILENO_HPP
+#define PYTHONIC_IO__IO_TEXTIOWRAPPER_FILENO_HPP
+
+#include "pythonic/include/io/_io/TextIOWrapper/fileno.hpp"
+#include "pythonic/builtins/file/fileno.hpp"
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/flush.hpp b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/flush.hpp
new file mode 100644
index 00000000000..b082f39d250
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/flush.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_IO__IO_TEXTIOWRAPPER_FLUSH_HPP
+#define PYTHONIC_IO__IO_TEXTIOWRAPPER_FLUSH_HPP
+
+#include "pythonic/include/io/_io/TextIOWrapper/flush.hpp"
+#include "pythonic/builtins/file/flush.hpp"
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/isatty.hpp b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/isatty.hpp
new file mode 100644
index 00000000000..10c3faa4f33
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/isatty.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_IO__IO_TEXTIOWRAPPER_ISATTY_HPP
+#define PYTHONIC_IO__IO_TEXTIOWRAPPER_ISATTY_HPP
+
+#include "pythonic/include/io/_io/TextIOWrapper/isatty.hpp"
+#include "pythonic/builtins/file/isatty.hpp"
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/next.hpp b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/next.hpp
new file mode 100644
index 00000000000..f3728768715
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/next.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_IO__IO_TEXTIOWRAPPER_NEXT_HPP
+#define PYTHONIC_IO__IO_TEXTIOWRAPPER_NEXT_HPP
+
+#include "pythonic/include/io/_io/TextIOWrapper/next.hpp"
+#include "pythonic/builtins/file/next.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/read.hpp b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/read.hpp
new file mode 100644
index 00000000000..b684eb8a56c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/read.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_IO__IO_TEXTIOWRAPPER_READ_HPP
+#define PYTHONIC_IO__IO_TEXTIOWRAPPER_READ_HPP
+
+#include "pythonic/include/io/_io/TextIOWrapper/read.hpp"
+#include "pythonic/builtins/file/read.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/readline.hpp b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/readline.hpp
new file mode 100644
index 00000000000..326bec25f8a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/readline.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_IO__IO_TEXTIOWRAPPER_READLINE_HPP
+#define PYTHONIC_IO__IO_TEXTIOWRAPPER_READLINE_HPP
+
+#include "pythonic/include/io/_io/TextIOWrapper/readline.hpp"
+#include "pythonic/builtins/file/readline.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/readlines.hpp b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/readlines.hpp
new file mode 100644
index 00000000000..d3aa0b16697
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/readlines.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_IO__IO_TEXTIOWRAPPER_READLINES_HPP
+#define PYTHONIC_IO__IO_TEXTIOWRAPPER_READLINES_HPP
+
+#include "pythonic/include/io/_io/TextIOWrapper/readlines.hpp"
+#include "pythonic/builtins/file/readlines.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/seek.hpp b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/seek.hpp
new file mode 100644
index 00000000000..ecc145890b4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/seek.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_IO__IO_TEXTIOWRAPPER_SEEK_HPP
+#define PYTHONIC_IO__IO_TEXTIOWRAPPER_SEEK_HPP
+
+#include "pythonic/include/io/_io/TextIOWrapper/seek.hpp"
+#include "pythonic/builtins/file/seek.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/tell.hpp b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/tell.hpp
new file mode 100644
index 00000000000..616d5c4cd0d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/tell.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_IO__IO_TEXTIOWRAPPER_TELL_HPP
+#define PYTHONIC_IO__IO_TEXTIOWRAPPER_TELL_HPP
+
+#include "pythonic/include/io/_io/TextIOWrapper/tell.hpp"
+#include "pythonic/builtins/file/tell.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/truncate.hpp b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/truncate.hpp
new file mode 100644
index 00000000000..26f1ad63223
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/truncate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_IO__IO_TEXTIOWRAPPER_TRUNCATE_HPP
+#define PYTHONIC_IO__IO_TEXTIOWRAPPER_TRUNCATE_HPP
+
+#include "pythonic/include/io/_io/TextIOWrapper/truncate.hpp"
+#include "pythonic/builtins/file/truncate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/write.hpp b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/write.hpp
new file mode 100644
index 00000000000..2a229ebcd35
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/write.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_IO__IO_TEXTIOWRAPPER_WRITE_HPP
+#define PYTHONIC_IO__IO_TEXTIOWRAPPER_WRITE_HPP
+
+#include "pythonic/include/io/_io/TextIOWrapper/write.hpp"
+#include "pythonic/builtins/file/write.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/writelines.hpp b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/writelines.hpp
new file mode 100644
index 00000000000..f0749fd41af
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/io/_io/TextIOWrapper/writelines.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_IO__IO_TEXTIOWRAPPER_WRITELINES_HPP
+#define PYTHONIC_IO__IO_TEXTIOWRAPPER_WRITELINES_HPP
+
+#include "pythonic/include/io/_io/TextIOWrapper/writelines.hpp"
+#include "pythonic/builtins/file/writelines.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/itertools/combinations.hpp b/contrib/python/pythran/pythran/pythonic/itertools/combinations.hpp
new file mode 100644
index 00000000000..b64e5780e17
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/itertools/combinations.hpp
@@ -0,0 +1,133 @@
+#ifndef PYTHONIC_ITERTOOLS_COMBINATIONS_HPP
+#define PYTHONIC_ITERTOOLS_COMBINATIONS_HPP
+
+#include "pythonic/include/itertools/combinations.hpp"
+
+#include "pythonic/types/dynamic_tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <numeric>
+
+PYTHONIC_NS_BEGIN
+
+namespace itertools
+{
+ namespace details
+ {
+ template <class T>
+ template <class Iter>
+ combination_iterator<T>::combination_iterator(Iter &&pool, long r)
+ : pool(pool.begin(), pool.end()), indices(r), r(r),
+ stopped(r > long(this->pool.size()))
+ {
+ assert(r >= 0 && "r must be non-negative");
+ if (!stopped) {
+ std::iota(indices.begin(), indices.end(), 0);
+ result.insert(result.end(), this->pool.begin(), this->pool.begin() + r);
+ }
+ }
+
+ template <class T>
+ combination_iterator<T>::combination_iterator(bool) : stopped(true)
+ {
+ }
+
+ template <class T>
+ types::dynamic_tuple<typename T::value_type>
+ combination_iterator<T>::operator*() const
+ {
+ assert(!stopped && "! stopped");
+ return {result.begin(), result.end()};
+ }
+
+ template <class T>
+ combination_iterator<T> &combination_iterator<T>::operator++()
+ {
+ /* Scan indices right-to-left until finding one that is !
+ at its maximum (i + n - r). */
+ long i, n = pool.size();
+ for (i = r - 1; i >= 0 && indices[i] == i + n - r; i--)
+ ;
+
+ /* If i is negative, then the indices are all at
+ their maximum value && we're done. */
+ if (i < 0)
+ stopped = true;
+ else {
+ /* Increment the current index which we know is ! at its
+ maximum. Then move back to the right setting each index
+ to its lowest possible value (one higher than the index
+ to its left -- this maintains the sort order invariant). */
+ indices[i]++;
+ for (long j = i + 1; j < r; j++)
+ indices[j] = indices[j - 1] + 1;
+
+ /* Update the result tuple for the new indices
+ starting with i, the leftmost index that changed */
+ for (; i < r; i++) {
+ result[i] = pool[indices[i]];
+ }
+ }
+ return *this;
+ }
+
+ template <class T>
+ bool
+ combination_iterator<T>::operator!=(combination_iterator const &other) const
+ {
+ assert(stopped || other.stopped);
+ return !(*this == other);
+ }
+
+ template <class T>
+ bool
+ combination_iterator<T>::operator==(combination_iterator const &other) const
+ {
+ assert(stopped || other.stopped);
+ return other.stopped == stopped;
+ }
+
+ template <class T>
+ bool
+ combination_iterator<T>::operator<(combination_iterator const &other) const
+ {
+ return stopped != other.stopped;
+ }
+
+ template <class T>
+ template <class Iter>
+ combination<T>::combination(Iter &&iter, long elts)
+ : iterator(std::forward<Iter>(iter), elts), num_elts(elts)
+ {
+ }
+
+ template <class T>
+ typename combination<T>::iterator const &combination<T>::begin() const
+ {
+ return *this;
+ }
+
+ template <class T>
+ typename combination<T>::iterator combination<T>::begin()
+ {
+ return *this;
+ }
+
+ template <class T>
+ typename combination<T>::iterator combination<T>::end() const
+ {
+ return {true};
+ }
+ } // namespace details
+
+ template <typename T0>
+ details::combination<
+ typename std::remove_cv<typename std::remove_reference<T0>::type>::type>
+ combinations(T0 &&iter, long num_elts)
+ {
+ return {std::forward<T0>(iter), num_elts};
+ }
+} // namespace itertools
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/itertools/common.hpp b/contrib/python/pythran/pythran/pythonic/itertools/common.hpp
new file mode 100644
index 00000000000..f5e212fce79
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/itertools/common.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_ITERTOOLS_COMMON_HPP
+#define PYTHONIC_ITERTOOLS_COMMON_HPP
+
+#include "pythonic/include/itertools/common.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/itertools/count.hpp b/contrib/python/pythran/pythran/pythonic/itertools/count.hpp
new file mode 100644
index 00000000000..c549bb46152
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/itertools/count.hpp
@@ -0,0 +1,103 @@
+#ifndef PYTHONIC_ITERTOOLS_COUNT_HPP
+#define PYTHONIC_ITERTOOLS_COUNT_HPP
+
+#include "pythonic/include/itertools/count.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <limits>
+
+PYTHONIC_NS_BEGIN
+
+namespace itertools
+{
+ namespace details
+ {
+ template <class T>
+ count_iterator<T>::count_iterator(T value, T step)
+ : value(value), step(step)
+ {
+ }
+
+ template <class T>
+ T count_iterator<T>::operator*() const
+ {
+ return value;
+ }
+
+ template <class T>
+ count_iterator<T> &count_iterator<T>::operator++()
+ {
+ value += step;
+ return *this;
+ }
+
+ template <class T>
+ count_iterator<T> &count_iterator<T>::operator+=(long n)
+ {
+ value += step * n;
+ return *this;
+ }
+
+ template <class T>
+ bool count_iterator<T>::operator!=(count_iterator const &other) const
+ {
+ return value != other.value;
+ }
+
+ template <class T>
+ bool count_iterator<T>::operator==(count_iterator const &other) const
+ {
+ return value == other.value;
+ }
+
+ template <class T>
+ bool count_iterator<T>::operator<(count_iterator const &other) const
+ {
+ return value < other.value;
+ }
+
+ template <class T>
+ long count_iterator<T>::operator-(count_iterator const &other) const
+ {
+ return (value - other.value) / step;
+ }
+
+ template <class T>
+ count<T>::count(T value, T step) : count_iterator<T>(value, step)
+ {
+ }
+
+ template <class T>
+ typename count<T>::iterator &count<T>::begin()
+ {
+ return *this;
+ }
+
+ template <class T>
+ typename count<T>::iterator const &count<T>::begin() const
+ {
+ return *this;
+ }
+
+ template <class T>
+ typename count<T>::iterator count<T>::end() const
+ {
+ return {std::numeric_limits<T>::max(), count_iterator<T>::step};
+ }
+ } // namespace details
+
+ template <typename T0, typename T1>
+ details::count<typename __combined<T0, T1>::type> count(T0 start, T1 step)
+ {
+ using return_t = typename __combined<T0, T1>::type;
+ return {static_cast<return_t>(start), static_cast<return_t>(step)};
+ }
+
+ inline details::count<long> count()
+ {
+ return {0, 1};
+ }
+} // namespace itertools
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/itertools/ifilter.hpp b/contrib/python/pythran/pythran/pythonic/itertools/ifilter.hpp
new file mode 100644
index 00000000000..b0fe9ab46ff
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/itertools/ifilter.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_ITERTOOLS_IFILTER_HPP
+#define PYTHONIC_ITERTOOLS_IFILTER_HPP
+
+#include "pythonic/builtins/filter.hpp"
+#include "pythonic/include/itertools/ifilter.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace itertools
+{
+
+ template <typename Operator, typename List0>
+ details::filter<typename std::remove_cv<
+ typename std::remove_reference<Operator>::type>::type,
+ typename std::remove_cv<
+ typename std::remove_reference<List0>::type>::type>
+ ifilter(Operator &&_op, List0 &&_seq)
+ {
+ return {std::forward<Operator>(_op), std::forward<List0>(_seq)};
+ }
+} // namespace itertools
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/itertools/islice.hpp b/contrib/python/pythran/pythran/pythonic/itertools/islice.hpp
new file mode 100644
index 00000000000..f8bda4f878c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/itertools/islice.hpp
@@ -0,0 +1,128 @@
+#ifndef PYTHONIC_ITERTOOLS_ISLICE_HPP
+#define PYTHONIC_ITERTOOLS_ISLICE_HPP
+
+#include "pythonic/include/itertools/islice.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/itertools/common.hpp"
+#include "pythonic/builtins/range.hpp"
+#include <iterator>
+
+PYTHONIC_NS_BEGIN
+
+namespace itertools
+{
+ template <typename Iterable>
+ islice_iterator<Iterable>::islice_iterator()
+ {
+ }
+
+ template <typename Iterable>
+ islice_iterator<Iterable>::islice_iterator(Iterable const &iterable,
+ builtins::range const &xr)
+ : iterable_ref(iterable), iterable(iterable_ref.begin()), xr_ref(xr),
+ state(xr_ref.begin()), prev(*state)
+ {
+ std::advance(this->iterable, *state);
+ }
+
+ template <typename Iterable>
+ islice_iterator<Iterable>::islice_iterator(npos const &n,
+ Iterable const &iterable,
+ builtins::range const &xr)
+ : iterable_ref(iterable), iterable(iterable_ref.begin()), xr_ref(xr),
+ state(xr_ref.end()), prev(0)
+ {
+ }
+
+ template <typename Iterable>
+ typename Iterable::value_type islice_iterator<Iterable>::operator*() const
+ {
+ return *iterable;
+ }
+
+ template <typename Iterable>
+ islice_iterator<Iterable> &islice_iterator<Iterable>::operator++()
+ {
+ ++state;
+ std::advance(this->iterable, *state - prev);
+ prev = *state;
+ return *this;
+ }
+
+ template <typename Iterable>
+ bool islice_iterator<Iterable>::
+ operator==(islice_iterator<Iterable> const &other) const
+ {
+ return (state == other.state);
+ }
+
+ template <typename Iterable>
+ bool islice_iterator<Iterable>::
+ operator!=(islice_iterator<Iterable> const &other) const
+ {
+ return state != other.state;
+ }
+
+ template <typename Iterable>
+ bool islice_iterator<Iterable>::
+ operator<(islice_iterator<Iterable> const &other) const
+ {
+ return state != other.state;
+ }
+
+ template <typename Iterable>
+ int islice_iterator<Iterable>::
+ operator-(islice_iterator<Iterable> const &other) const
+ {
+ return state - other.state;
+ }
+
+ template <typename Iterable>
+ _islice<Iterable>::_islice()
+ {
+ }
+
+ template <typename Iterable>
+ _islice<Iterable>::_islice(Iterable const &iterable,
+ builtins::range const &xr)
+ : iterator(iterable, xr), end_iter(npos(), iterable, xr)
+ {
+ }
+
+ template <typename Iterable>
+ typename _islice<Iterable>::iterator &_islice<Iterable>::begin()
+ {
+ return *this;
+ }
+
+ template <typename Iterable>
+ typename _islice<Iterable>::iterator const &_islice<Iterable>::begin() const
+ {
+ return *this;
+ }
+
+ template <typename Iterable>
+ typename _islice<Iterable>::iterator _islice<Iterable>::end() const
+ {
+ return end_iter;
+ }
+
+ template <typename Iterable>
+ _islice<typename std::remove_cv<
+ typename std::remove_reference<Iterable>::type>::type>
+ islice(Iterable &&iterable, long start, long stop, long step)
+ {
+ return {iterable, builtins::range(start, stop, step)};
+ }
+
+ template <typename Iterable>
+ _islice<typename std::remove_cv<
+ typename std::remove_reference<Iterable>::type>::type>
+ islice(Iterable &&iterable, long stop)
+ {
+ return {iterable, builtins::range(0, stop, 1)};
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/itertools/permutations.hpp b/contrib/python/pythran/pythran/pythonic/itertools/permutations.hpp
new file mode 100644
index 00000000000..2dd2e4feabe
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/itertools/permutations.hpp
@@ -0,0 +1,178 @@
+#ifndef PYTHONIC_ITERTOOLS_PERMUTATIONS_HPP
+#define PYTHONIC_ITERTOOLS_PERMUTATIONS_HPP
+
+#include "pythonic/builtins/range.hpp"
+#include "pythonic/include/itertools/permutations.hpp"
+#include "pythonic/types/dynamic_tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+
+PYTHONIC_NS_BEGIN
+
+namespace itertools
+{
+
+ template <class T, class H>
+ permutations_iterator<T, H>::permutations_iterator()
+ {
+ }
+
+ template <class T, class H>
+ permutations_iterator<T, H>::permutations_iterator(pool_type const &iter,
+ size_t num_elts, bool end)
+ : pool(iter), curr_permut(pool.size()), _size(num_elts), end(end)
+ {
+ std::iota(curr_permut.begin(), curr_permut.end(), 0);
+ if (num_elts > iter.size()) {
+ end = true;
+ }
+ }
+
+ template <class T>
+ types::dynamic_tuple<T> init_permut_from(size_t n, types::dynamic_tuple<T> *)
+ {
+ types::dynamic_tuple<T> res;
+ res.data->resize(n);
+ return res;
+ }
+ template <class T, size_t N>
+ types::array<T, N> init_permut_from(size_t n, types::array<T, N> *)
+ {
+ assert(N == n && "consistent init");
+ return {};
+ }
+
+ template <class T, class H>
+ H permutations_iterator<T, H>::operator*() const
+ {
+ H res = init_permut_from(_size, (H *)nullptr);
+ for (size_t i = 0; i < _size; i++)
+ res[i] = pool[curr_permut[i]]; // Ok because types::dynamic_tuple is
+ // indeed a vector
+ return res;
+ }
+
+ template <class T, class I>
+ types::dynamic_tuple<T> init_permut_from(I begin, I end,
+ types::dynamic_tuple<T> *)
+ {
+ return {begin, end};
+ }
+ template <class T, size_t N, class I>
+ types::array<T, N> init_permut_from(I begin, I end, types::array<T, N> *)
+ {
+ types::array<T, N> res;
+ std::copy(begin, end, res.begin());
+ return res;
+ }
+
+ template <class T, class H>
+ permutations_iterator<T, H> &permutations_iterator<T, H>::operator++()
+ {
+ if (_size != pool.size()) {
+ // Slow path, the iterator is a "view" of a prefix smaller
+ // than the the pool size
+ // FIXME a better implementation would be to avoid
+ // std::next_permutation, but only in the slow path
+ H prev_permut = init_permut_from(
+ curr_permut.begin(), curr_permut.begin() + _size, (H *)nullptr);
+ while ((end = std::next_permutation(curr_permut.begin(),
+ curr_permut.end()))) {
+ // Check if the prefix of the new permutation is
+ // different of the previous one
+ H new_permut = init_permut_from(
+ curr_permut.begin(), curr_permut.begin() + _size, (H *)nullptr);
+ if (!(prev_permut == new_permut))
+ break;
+ }
+ } else
+ end = std::next_permutation(curr_permut.begin(), curr_permut.end());
+ return *this;
+ }
+
+ template <class T, class H>
+ bool permutations_iterator<T, H>::operator!=(
+ permutations_iterator<T, H> const &other) const
+ {
+ return !(*this == other);
+ }
+
+ template <class T, class H>
+ bool permutations_iterator<T, H>::operator==(
+ permutations_iterator<T, H> const &other) const
+ {
+ if (other.end != end)
+ return false;
+ return std::equal(curr_permut.begin(), curr_permut.end(),
+ other.curr_permut.begin());
+ }
+
+ template <class T, class H>
+ bool permutations_iterator<T, H>::operator<(
+ permutations_iterator<T, H> const &other) const
+ {
+ if (end != other.end)
+ return end > other.end;
+ for (long i = 0; i < pool.size(); i++)
+ if (other.curr_permut[i] < curr_permut[i])
+ return false;
+ else if (other.curr_permut[i] > curr_permut[i])
+ return true;
+ return false;
+ }
+
+ template <class T, class H>
+ _permutations<T, H>::_permutations()
+ {
+ }
+
+ template <class T, class H>
+ _permutations<T, H>::_permutations(T iter, long elts)
+ : iterator({iter.begin(), iter.end()}, elts, true)
+ {
+ }
+
+ template <class T, class H>
+ typename _permutations<T, H>::iterator const &
+ _permutations<T, H>::begin() const
+ {
+ return *this;
+ }
+
+ template <class T, class H>
+ typename _permutations<T, H>::iterator _permutations<T, H>::begin()
+ {
+ return *this;
+ }
+
+ template <class T, class H>
+ typename _permutations<T, H>::iterator _permutations<T, H>::end() const
+ {
+ return iterator(iterator::pool, iterator::_size, false);
+ }
+
+ template <typename T0>
+ _permutations<T0, types::dynamic_tuple<typename T0::value_type>>
+ permutations(T0 iter, long num_elts)
+ {
+ return {iter, num_elts};
+ }
+
+ template <typename T0>
+ _permutations<T0, types::dynamic_tuple<typename T0::value_type>>
+ permutations(T0 iter)
+ {
+ return {iter, std::distance(iter.begin(), iter.end())};
+ }
+
+ template <typename T, long N>
+ _permutations<T, types::array<typename T::value_type, (size_t)N>>
+ permutations(T iter, std::integral_constant<long, N>)
+ {
+ return {iter, N};
+ }
+} // namespace itertools
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/itertools/product.hpp b/contrib/python/pythran/pythran/pythonic/itertools/product.hpp
new file mode 100644
index 00000000000..db31e83c780
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/itertools/product.hpp
@@ -0,0 +1,144 @@
+#ifndef PYTHONIC_ITERTOOLS_PRODUCT_HPP
+#define PYTHONIC_ITERTOOLS_PRODUCT_HPP
+
+#include "pythonic/include/itertools/product.hpp"
+#include "pythonic/utils/int_.hpp"
+#include "pythonic/utils/seq.hpp"
+#include "pythonic/utils/iterator.hpp"
+#include "pythonic/itertools/common.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace itertools
+{
+ namespace details
+ {
+
+ /// product iterator implementation
+
+ template <typename... Iters>
+ template <size_t... I>
+ product_iterator<Iters...>::product_iterator(
+ std::tuple<Iters...> &_iters, utils::index_sequence<I...> const &)
+ : it_begin(std::get<I>(_iters).begin()...),
+ it_end(std::get<I>(_iters).end()...),
+ it(std::get<I>(_iters).begin()...), end(it_begin == it_end)
+ {
+ }
+
+ template <typename... Iters>
+ template <size_t... I>
+ product_iterator<Iters...>::product_iterator(
+ npos, std::tuple<Iters...> &_iters, utils::index_sequence<I...> const &)
+ : it_begin(std::get<I>(_iters).end()...),
+ it_end(std::get<I>(_iters).end()...),
+ it(std::get<I>(_iters).end()...), end(true)
+ {
+ }
+
+ template <typename... Iters>
+ template <size_t... I>
+ types::make_tuple_t<typename Iters::value_type...>
+ product_iterator<Iters...>::get_value(
+ utils::index_sequence<I...> const &) const
+ {
+ return types::make_tuple(*std::get<I>(it)...);
+ }
+
+ template <typename... Iters>
+ types::make_tuple_t<typename Iters::value_type...>
+ product_iterator<Iters...>::operator*() const
+ {
+ return get_value(utils::make_index_sequence<sizeof...(Iters)>{});
+ }
+
+ template <typename... Iters>
+ template <size_t N>
+ void product_iterator<Iters...>::advance(utils::int_<N>)
+ {
+ if (++std::get<N>(it) == std::get<N>(it_end)) {
+ std::get<N>(it) = std::get<N>(it_begin);
+ advance(utils::int_<N - 1>());
+ }
+ }
+
+ template <typename... Iters>
+ void product_iterator<Iters...>::advance(utils::int_<0>)
+ {
+ if (++std::get<0>(it) == std::get<0>(it_end))
+ end = true;
+ }
+
+ template <typename... Iters>
+ product_iterator<Iters...> &product_iterator<Iters...>::operator++()
+ {
+ advance(utils::int_<sizeof...(Iters)-1>{});
+ return *this;
+ }
+
+ template <typename... Iters>
+ bool product_iterator<Iters...>::
+ operator==(product_iterator<Iters...> const &other) const
+ {
+ return end == other.end;
+ }
+
+ template <typename... Iters>
+ bool product_iterator<Iters...>::
+ operator!=(product_iterator<Iters...> const &other) const
+ {
+ return end != other.end;
+ }
+
+ template <typename... Iters>
+ bool product_iterator<Iters...>::
+ operator<(product_iterator<Iters...> const &other) const
+ {
+ return end != other.end;
+ }
+
+ /// details product implementation
+
+ // FIXME: Iterators need to be evaluated as they may be used multiple
+ // times
+ template <typename... Iters>
+ product<Iters...>::product(Iters const &... _iters)
+ : utils::iterator_reminder<true, Iters...>(_iters...),
+ iterator(this->values,
+ utils::make_index_sequence<sizeof...(Iters)>{}),
+ end_iter(npos(), this->values,
+ utils::make_index_sequence<sizeof...(Iters)>{})
+ {
+ }
+
+ template <typename... Iters>
+ typename product<Iters...>::iterator &product<Iters...>::begin()
+ {
+ return *this;
+ }
+
+ template <typename... Iters>
+ typename product<Iters...>::iterator const &product<Iters...>::begin() const
+ {
+ return *this;
+ }
+
+ template <typename... Iters>
+ typename product<Iters...>::iterator const &product<Iters...>::end() const
+ {
+ return end_iter;
+ }
+ }
+
+ template <typename... Iter>
+ details::product<typename std::remove_cv<
+ typename std::remove_reference<Iter>::type>::type...>
+ product(Iter &&... iters)
+ {
+ return {std::forward<Iter>(iters)...};
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/itertools/repeat.hpp b/contrib/python/pythran/pythran/pythonic/itertools/repeat.hpp
new file mode 100644
index 00000000000..cbaffb86265
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/itertools/repeat.hpp
@@ -0,0 +1,82 @@
+#ifndef PYTHONIC_ITERTOOLS_REPEAT_HPP
+#define PYTHONIC_ITERTOOLS_REPEAT_HPP
+
+#include "pythonic/include/itertools/repeat.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/list.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace itertools
+{
+
+ template <class T, bool Endless>
+ repeat_iterator<T, Endless>::repeat_iterator(T value, long count)
+ : value_(value), count_(count)
+ {
+ }
+
+ template <class T, bool Endless>
+ repeat_iterator<T, Endless> &repeat_iterator<T, Endless>::operator++()
+ {
+ ++count_;
+ return *this;
+ }
+
+ template <class T, bool Endless>
+ T repeat_iterator<T, Endless>::operator*()
+ {
+ return value_;
+ }
+
+ template <class T, bool Endless>
+ bool repeat_iterator<T, Endless>::
+ operator!=(repeat_iterator<T, Endless> const &other) const
+ {
+ return Endless || count_ != other.count_;
+ }
+ template <class T, bool Endless>
+ bool repeat_iterator<T, Endless>::
+ operator==(repeat_iterator<T, Endless> const &other) const
+ {
+ return !Endless && count_ == other.count_;
+ }
+ template <class T, bool Endless>
+ bool repeat_iterator<T, Endless>::
+ operator<(repeat_iterator<T, Endless> const &other) const
+ {
+ return !Endless && count_ < other.count_;
+ }
+
+ template <class T, bool Endless>
+ _repeat<T, Endless>::_repeat(T value, long count)
+ : repeat_iterator<T, Endless>(value, count)
+ {
+ }
+
+ template <class T, bool Endless>
+ typename _repeat<T, Endless>::iterator _repeat<T, Endless>::begin() const
+ {
+ return {_repeat<T, Endless>::iterator::value_, 0};
+ }
+ template <class T, bool Endless>
+ typename _repeat<T, Endless>::iterator _repeat<T, Endless>::end() const
+ {
+ return *this;
+ }
+
+ template <typename T>
+ _repeat<T, false> repeat(T value, long count)
+ {
+ return {value, count};
+ }
+
+ template <typename T>
+ _repeat<T, true> repeat(T value)
+ {
+ return {value, -1};
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/acos.hpp b/contrib/python/pythran/pythran/pythonic/math/acos.hpp
new file mode 100644
index 00000000000..5b7a0359a0b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/acos.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_ACOS_HPP
+#define PYTHONIC_MATH_ACOS_HPP
+
+#include "pythonic/include/math/acos.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/acosh.hpp b/contrib/python/pythran/pythran/pythonic/math/acosh.hpp
new file mode 100644
index 00000000000..09a0eb72e9a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/acosh.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_ACOSH_HPP
+#define PYTHONIC_MATH_ACOSH_HPP
+
+#include "pythonic/include/math/acosh.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/asin.hpp b/contrib/python/pythran/pythran/pythonic/math/asin.hpp
new file mode 100644
index 00000000000..32cb90a3d7a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/asin.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_ASIN_HPP
+#define PYTHONIC_MATH_ASIN_HPP
+
+#include "pythonic/include/math/asin.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/asinh.hpp b/contrib/python/pythran/pythran/pythonic/math/asinh.hpp
new file mode 100644
index 00000000000..c5625efc506
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/asinh.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_ASINH_HPP
+#define PYTHONIC_MATH_ASINH_HPP
+
+#include "pythonic/include/math/asinh.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/atan.hpp b/contrib/python/pythran/pythran/pythonic/math/atan.hpp
new file mode 100644
index 00000000000..2f3b56bd2da
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/atan.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_ATAN_HPP
+#define PYTHONIC_MATH_ATAN_HPP
+
+#include "pythonic/include/math/atan.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/atan2.hpp b/contrib/python/pythran/pythran/pythonic/math/atan2.hpp
new file mode 100644
index 00000000000..418c6ee9566
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/atan2.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_ATAN2_HPP
+#define PYTHONIC_MATH_ATAN2_HPP
+
+#include "pythonic/include/math/atan2.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/atanh.hpp b/contrib/python/pythran/pythran/pythonic/math/atanh.hpp
new file mode 100644
index 00000000000..cf36b7e3950
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/atanh.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_ATANH_HPP
+#define PYTHONIC_MATH_ATANH_HPP
+
+#include "pythonic/include/math/atanh.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/ceil.hpp b/contrib/python/pythran/pythran/pythonic/math/ceil.hpp
new file mode 100644
index 00000000000..f39319198d7
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/ceil.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_MATH_CEIL_HPP
+#define PYTHONIC_MATH_CEIL_HPP
+
+#include "pythonic/include/math/ceil.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ template <class T>
+ long ceil(T x)
+ {
+ return std::ceil(x);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/copysign.hpp b/contrib/python/pythran/pythran/pythonic/math/copysign.hpp
new file mode 100644
index 00000000000..df1d2b4f6e2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/copysign.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_COPYSIGN_HPP
+#define PYTHONIC_MATH_COPYSIGN_HPP
+
+#include "pythonic/include/math/copysign.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/cos.hpp b/contrib/python/pythran/pythran/pythonic/math/cos.hpp
new file mode 100644
index 00000000000..508eb6fd100
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/cos.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_COS_HPP
+#define PYTHONIC_MATH_COS_HPP
+
+#include "pythonic/include/math/cos.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/cosh.hpp b/contrib/python/pythran/pythran/pythonic/math/cosh.hpp
new file mode 100644
index 00000000000..00040b3b53b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/cosh.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_COSH_HPP
+#define PYTHONIC_MATH_COSH_HPP
+
+#include "pythonic/include/math/cosh.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/degrees.hpp b/contrib/python/pythran/pythran/pythonic/math/degrees.hpp
new file mode 100644
index 00000000000..b3d43b2a4d1
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/degrees.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_MATH_DEGREES_HPP
+#define PYTHONIC_MATH_DEGREES_HPP
+
+#include "pythonic/include/math/degrees.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/math/pi.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+
+ template <class T>
+ double degrees(T x)
+ {
+ return (x * 360.) / (2. * pi);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/e.hpp b/contrib/python/pythran/pythran/pythonic/math/e.hpp
new file mode 100644
index 00000000000..e4e493eba2a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/e.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_MATH_E_HPP
+#define PYTHONIC_MATH_E_HPP
+
+#include "pythonic/include/math/e.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/erf.hpp b/contrib/python/pythran/pythran/pythonic/math/erf.hpp
new file mode 100644
index 00000000000..dbe3b95a41a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/erf.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_ERF_HPP
+#define PYTHONIC_MATH_ERF_HPP
+
+#include "pythonic/include/math/erf.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/erfc.hpp b/contrib/python/pythran/pythran/pythonic/math/erfc.hpp
new file mode 100644
index 00000000000..6f53255fd44
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/erfc.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_ERFC_HPP
+#define PYTHONIC_MATH_ERFC_HPP
+
+#include "pythonic/include/math/erfc.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/exp.hpp b/contrib/python/pythran/pythran/pythonic/math/exp.hpp
new file mode 100644
index 00000000000..140b2f35cb2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/exp.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_EXP_HPP
+#define PYTHONIC_MATH_EXP_HPP
+
+#include "pythonic/include/math/exp.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/expm1.hpp b/contrib/python/pythran/pythran/pythonic/math/expm1.hpp
new file mode 100644
index 00000000000..0652b508e9c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/expm1.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_EXPM1_HPP
+#define PYTHONIC_MATH_EXPM1_HPP
+
+#include "pythonic/include/math/expm1.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/fabs.hpp b/contrib/python/pythran/pythran/pythonic/math/fabs.hpp
new file mode 100644
index 00000000000..817a9bbd820
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/fabs.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_FABS_HPP
+#define PYTHONIC_MATH_FABS_HPP
+
+#include "pythonic/include/math/fabs.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/factorial.hpp b/contrib/python/pythran/pythran/pythonic/math/factorial.hpp
new file mode 100644
index 00000000000..5b7b4d63845
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/factorial.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_MATH_FACTORIAL_HPP
+#define PYTHONIC_MATH_FACTORIAL_HPP
+
+#include "pythonic/include/math/factorial.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+
+ template <class T>
+ T factorial(T x)
+ {
+ long res = 1;
+ for (long i = 2; i <= x; i++)
+ res *= i;
+ return res;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/floor.hpp b/contrib/python/pythran/pythran/pythonic/math/floor.hpp
new file mode 100644
index 00000000000..f30c2bac631
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/floor.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_MATH_FLOOR_HPP
+#define PYTHONIC_MATH_FLOOR_HPP
+
+#include "pythonic/include/math/floor.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ template <class T>
+ long floor(T x)
+ {
+ return std::floor(x);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/fmod.hpp b/contrib/python/pythran/pythran/pythonic/math/fmod.hpp
new file mode 100644
index 00000000000..f19505de211
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/fmod.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_FMOD_HPP
+#define PYTHONIC_MATH_FMOD_HPP
+
+#include "pythonic/include/math/fmod.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/frexp.hpp b/contrib/python/pythran/pythran/pythonic/math/frexp.hpp
new file mode 100644
index 00000000000..2a694c703df
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/frexp.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_MATH_FREXP_HPP
+#define PYTHONIC_MATH_FREXP_HPP
+
+#include "pythonic/include/math/frexp.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/tuple.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ std::tuple<double, long> frexp(double x)
+ {
+ int exp;
+ double sig = std::frexp(x, &exp);
+ return std::tuple<double, long>(sig, exp);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/gamma.hpp b/contrib/python/pythran/pythran/pythonic/math/gamma.hpp
new file mode 100644
index 00000000000..caf5ed5c926
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/gamma.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_MATH_GAMMA_HPP
+#define PYTHONIC_MATH_GAMMA_HPP
+
+#include "pythonic/include/math/gamma.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ double gamma(double x)
+ {
+ return std::tgamma(x);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/hypot.hpp b/contrib/python/pythran/pythran/pythonic/math/hypot.hpp
new file mode 100644
index 00000000000..47e2422a9a6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/hypot.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_HYPOT_HPP
+#define PYTHONIC_MATH_HYPOT_HPP
+
+#include "pythonic/include/math/hypot.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/isinf.hpp b/contrib/python/pythran/pythran/pythonic/math/isinf.hpp
new file mode 100644
index 00000000000..063fa66a72b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/isinf.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_ISINF_HPP
+#define PYTHONIC_MATH_ISINF_HPP
+
+#include "pythonic/include/math/isinf.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/isnan.hpp b/contrib/python/pythran/pythran/pythonic/math/isnan.hpp
new file mode 100644
index 00000000000..3172c995b0f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/isnan.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_ISNAN_HPP
+#define PYTHONIC_MATH_ISNAN_HPP
+
+#include "pythonic/include/math/isnan.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/ldexp.hpp b/contrib/python/pythran/pythran/pythonic/math/ldexp.hpp
new file mode 100644
index 00000000000..8a5e90b0c4c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/ldexp.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_LDEXP_HPP
+#define PYTHONIC_MATH_LDEXP_HPP
+
+#include "pythonic/include/math/ldexp.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/lgamma.hpp b/contrib/python/pythran/pythran/pythonic/math/lgamma.hpp
new file mode 100644
index 00000000000..a631b248a94
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/lgamma.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_LGAMMA_HPP
+#define PYTHONIC_MATH_LGAMMA_HPP
+
+#include "pythonic/include/math/lgamma.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/log.hpp b/contrib/python/pythran/pythran/pythonic/math/log.hpp
new file mode 100644
index 00000000000..1c45f4bb98d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/log.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_MATH_LOG_HPP
+#define PYTHONIC_MATH_LOG_HPP
+
+#include "pythonic/include/math/log.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ using std::log;
+
+ inline double log(double x, double base)
+ {
+ return log(x) / log(base);
+ }
+} // namespace math
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/log10.hpp b/contrib/python/pythran/pythran/pythonic/math/log10.hpp
new file mode 100644
index 00000000000..39f40647d19
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/log10.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_LOG10_HPP
+#define PYTHONIC_MATH_LOG10_HPP
+
+#include "pythonic/include/math/log10.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/log1p.hpp b/contrib/python/pythran/pythran/pythonic/math/log1p.hpp
new file mode 100644
index 00000000000..68dc19528e5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/log1p.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_LOG1P_HPP
+#define PYTHONIC_MATH_LOG1P_HPP
+
+#include "pythonic/include/math/log1p.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/modf.hpp b/contrib/python/pythran/pythran/pythonic/math/modf.hpp
new file mode 100644
index 00000000000..fef342fe01a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/modf.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_MATH_MODF_HPP
+#define PYTHONIC_MATH_MODF_HPP
+
+#include "pythonic/include/math/modf.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/tuple.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+
+ std::tuple<double, double> modf(double x)
+ {
+ double i;
+ double frac = std::modf(x, &i);
+ return std::make_tuple(frac, i);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/pi.hpp b/contrib/python/pythran/pythran/pythonic/math/pi.hpp
new file mode 100644
index 00000000000..e3cb609b08f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/pi.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_MATH_PI_HPP
+#define PYTHONIC_MATH_PI_HPP
+
+#include "pythonic/include/math/pi.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/pow.hpp b/contrib/python/pythran/pythran/pythonic/math/pow.hpp
new file mode 100644
index 00000000000..fb4ed0a9233
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/pow.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_POW_HPP
+#define PYTHONIC_MATH_POW_HPP
+
+#include "pythonic/include/math/pow.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/radians.hpp b/contrib/python/pythran/pythran/pythonic/math/radians.hpp
new file mode 100644
index 00000000000..e45ee692edf
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/radians.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_MATH_RADIANS_HPP
+#define PYTHONIC_MATH_RADIANS_HPP
+
+#include "pythonic/include/math/radians.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/math/pi.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ template <class T>
+ double radians(T x)
+ {
+ return (x * 2. * pi) / 360.;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/sin.hpp b/contrib/python/pythran/pythran/pythonic/math/sin.hpp
new file mode 100644
index 00000000000..4b645692374
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/sin.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_SIN_HPP
+#define PYTHONIC_MATH_SIN_HPP
+
+#include "pythonic/include/math/sin.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/sinh.hpp b/contrib/python/pythran/pythran/pythonic/math/sinh.hpp
new file mode 100644
index 00000000000..def0133d06d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/sinh.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_SINH_HPP
+#define PYTHONIC_MATH_SINH_HPP
+
+#include "pythonic/include/math/sinh.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/sqrt.hpp b/contrib/python/pythran/pythran/pythonic/math/sqrt.hpp
new file mode 100644
index 00000000000..e738f7d4670
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/sqrt.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_SQRT_HPP
+#define PYTHONIC_MATH_SQRT_HPP
+
+#include "pythonic/include/math/sqrt.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/tan.hpp b/contrib/python/pythran/pythran/pythonic/math/tan.hpp
new file mode 100644
index 00000000000..e7db741fe30
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/tan.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_TAN_HPP
+#define PYTHONIC_MATH_TAN_HPP
+
+#include "pythonic/include/math/tan.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/tanh.hpp b/contrib/python/pythran/pythran/pythonic/math/tanh.hpp
new file mode 100644
index 00000000000..b6334be2158
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/tanh.hpp
@@ -0,0 +1,16 @@
+#ifndef PYTHONIC_MATH_TANH_HPP
+#define PYTHONIC_MATH_TANH_HPP
+
+#include "pythonic/include/math/tanh.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/math/trunc.hpp b/contrib/python/pythran/pythran/pythonic/math/trunc.hpp
new file mode 100644
index 00000000000..a45a7c7f1f6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/math/trunc.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_MATH_TRUNC_HPP
+#define PYTHONIC_MATH_TRUNC_HPP
+
+#include "pythonic/include/math/trunc.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace math
+{
+ template <class T>
+ long trunc(T x)
+ {
+ return x;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/NINF.hpp b/contrib/python/pythran/pythran/pythonic/numpy/NINF.hpp
new file mode 100644
index 00000000000..e3c30928ebc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/NINF.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_NUMPY_NINF_HPP
+#define PYTHONIC_NUMPY_NINF_HPP
+
+#include "pythonic/include/numpy/NINF.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/absolute.hpp b/contrib/python/pythran/pythran/pythonic/numpy/absolute.hpp
new file mode 100644
index 00000000000..59a10027eed
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/absolute.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_ABSOLUTE_HPP
+#define PYTHONIC_NUMPY_ABSOLUTE_HPP
+
+#include "pythonic/include/numpy/absolute.hpp"
+#include "pythonic/numpy/abs.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/add.hpp b/contrib/python/pythran/pythran/pythonic/numpy/add.hpp
new file mode 100644
index 00000000000..cfb74a8f3f2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/add.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_NUMPY_ADD_HPP
+#define PYTHONIC_NUMPY_ADD_HPP
+
+#include "pythonic/include/numpy/add.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/operator_/add.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME add
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::add
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/add/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/add/accumulate.hpp
new file mode 100644
index 00000000000..d97bbcca5cb
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/add/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_ADD_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_ADD_ACCUMULATE_HPP
+
+#define UFUNC_NAME add
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/add/reduce.hpp b/contrib/python/pythran/pythran/pythonic/numpy/add/reduce.hpp
new file mode 100644
index 00000000000..b457c2c321d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/add/reduce.hpp
@@ -0,0 +1,11 @@
+#ifndef PYTHONIC_NUMPY_ADD_REDUCE_HPP
+#define PYTHONIC_NUMPY_ADD_REDUCE_HPP
+
+#define UFUNC_NAME add
+#define UFUNC_INAME iadd
+#include "pythonic/include/numpy/add/reduce.hpp"
+#include "pythonic/numpy/ufunc_reduce.hpp"
+#undef UFUNC_NAME
+#undef UFUNC_INAME
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/alen.hpp b/contrib/python/pythran/pythran/pythonic/numpy/alen.hpp
new file mode 100644
index 00000000000..0b34f032826
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/alen.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_NUMPY_ALEN_HPP
+#define PYTHONIC_NUMPY_ALEN_HPP
+
+#include "pythonic/include/numpy/alen.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T>
+ long alen(T &&expr)
+ {
+ return expr.template shape<0>();
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/all.hpp b/contrib/python/pythran/pythran/pythonic/numpy/all.hpp
new file mode 100644
index 00000000000..3c4a8c750da
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/all.hpp
@@ -0,0 +1,98 @@
+#ifndef PYTHONIC_NUMPY_ALL_HPP
+#define PYTHONIC_NUMPY_ALL_HPP
+
+#include "pythonic/include/numpy/all.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/builtins/ValueError.hpp"
+#include "pythonic/numpy/multiply.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ bool _all(E begin, E end, utils::int_<1>)
+ {
+ return std::all_of(begin, end,
+ [](typename std::iterator_traits<E>::value_type e)
+ -> bool { return e; });
+ }
+
+ template <class E, size_t N>
+ bool _all(E begin, E end, utils::int_<N>)
+ {
+ for (; begin != end; ++begin)
+ if (!_all((*begin).begin(), (*begin).end(), utils::int_<N - 1>()))
+ return false;
+ return true;
+ }
+
+ template <class E>
+ typename std::enable_if<types::is_numexpr_arg<E>::value, bool>::type
+ all(E const &expr, types::none_type)
+ {
+ return _all(expr.begin(), expr.end(), utils::int_<E::value>());
+ }
+
+ template <class E>
+ typename std::enable_if<
+ std::is_scalar<E>::value || types::is_complex<E>::value, bool>::type
+ all(E const &expr, types::none_type)
+ {
+ return expr;
+ }
+
+ template <class E>
+ auto all(E const &array, long axis) ->
+ typename std::enable_if<std::is_scalar<E>::value ||
+ types::is_complex<E>::value,
+ decltype(all(array))>::type
+ {
+ if (axis != 0)
+ throw types::ValueError("axis out of bounds");
+ return all(array);
+ }
+
+ template <class E>
+ auto all(E const &array, long axis) ->
+ typename std::enable_if<E::value == 1, decltype(all(array))>::type
+ {
+ if (axis != 0)
+ throw types::ValueError("axis out of bounds");
+ return all(array);
+ }
+
+ template <class E>
+ typename std::enable_if<
+ E::value != 1,
+ types::ndarray<typename E::dtype, types::array<long, E::value - 1>>>::type
+ all(E const &array, long axis)
+ {
+ constexpr long N = E::value;
+ typedef typename E::dtype T;
+ if (axis < 0 || axis >= long(N))
+ throw types::ValueError("axis out of bounds");
+ if (axis == 0) {
+ types::array<long, N - 1> shp;
+ sutils::copy_shape<0, 1>(shp, array, utils::make_index_sequence<N - 1>());
+ types::ndarray<bool, types::array<long, N - 1>> out(shp, true);
+ return std::accumulate(array.begin(), array.end(), out,
+ functor::multiply());
+ } else {
+ types::array<long, N - 1> shp;
+ sutils::copy_shape<0, 0>(shp, array, utils::make_index_sequence<N - 1>());
+ types::ndarray<bool, types::array<long, N - 1>> ally(shp, builtins::None);
+ std::transform(
+ array.begin(), array.end(), ally.begin(),
+ [=](types::ndarray<T, types::array<long, N - 1>> const &other) {
+ return all(other, axis - 1);
+ });
+ return ally;
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/allclose.hpp b/contrib/python/pythran/pythran/pythonic/numpy/allclose.hpp
new file mode 100644
index 00000000000..3a78e441f0f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/allclose.hpp
@@ -0,0 +1,54 @@
+#ifndef PYTHONIC_NUMPY_ALLCLOSE_HPP
+#define PYTHONIC_NUMPY_ALLCLOSE_HPP
+
+#include "pythonic/include/numpy/allclose.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/numpy/abs.hpp"
+#include "pythonic/numpy/isfinite.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace
+ {
+ template <class I0, class I1>
+ bool _allclose(I0 begin, I0 end, I1 ibegin, double rtol, double atol,
+ utils::int_<1>)
+ {
+ for (; begin != end; ++begin, ++ibegin) {
+ auto u = *begin;
+ auto v = *ibegin;
+ if (((!functor::isfinite()(u) || !functor::isfinite()(v)) &&
+ u != v) || // Infinite && NaN cases
+ functor::abs()(u - v) > (atol + rtol * functor::abs()(v))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ template <class I0, class I1, size_t N>
+ bool _allclose(I0 begin, I0 end, I1 ibegin, double rtol, double atol,
+ utils::int_<N>)
+ {
+ for (; begin != end; ++begin, ++ibegin)
+ if (!_allclose((*begin).begin(), (*begin).end(), (*ibegin).begin(),
+ rtol, atol, utils::int_<N - 1>()))
+ return false;
+ return true;
+ }
+ }
+
+ template <class U, class V>
+ bool allclose(U const &u, V const &v, double rtol, double atol)
+ {
+ return _allclose(u.begin(), u.end(), v.begin(), rtol, atol,
+ utils::int_<U::value>());
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/alltrue.hpp b/contrib/python/pythran/pythran/pythonic/numpy/alltrue.hpp
new file mode 100644
index 00000000000..98674c88ef1
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/alltrue.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_NUMPY_ALLTRUE_HPP
+#define PYTHONIC_NUMPY_ALLTRUE_HPP
+
+#include "pythonic/include/numpy/alltrue.hpp"
+
+#include "pythonic/numpy/all.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class... Types>
+ auto alltrue(Types &&... types)
+ -> decltype(all(std::forward<Types>(types)...))
+ {
+ return all(std::forward<Types>(types)...);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/amax.hpp b/contrib/python/pythran/pythran/pythonic/numpy/amax.hpp
new file mode 100644
index 00000000000..76f0516c81d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/amax.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_AMAX_HPP
+#define PYTHONIC_NUMPY_AMAX_HPP
+
+#include "pythonic/include/numpy/amax.hpp"
+#include "pythonic/numpy/max.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/amin.hpp b/contrib/python/pythran/pythran/pythonic/numpy/amin.hpp
new file mode 100644
index 00000000000..955e8bbe92a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/amin.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_AMIN_HPP
+#define PYTHONIC_NUMPY_AMIN_HPP
+
+#include "pythonic/include/numpy/amin.hpp"
+#include "pythonic/numpy/min.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/angle.hpp b/contrib/python/pythran/pythran/pythonic/numpy/angle.hpp
new file mode 100644
index 00000000000..78ef2fd7f5c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/angle.hpp
@@ -0,0 +1,34 @@
+#ifndef PYTHONIC_NUMPY_ANGLE_HPP
+#define PYTHONIC_NUMPY_ANGLE_HPP
+
+#include "pythonic/include/numpy/angle.hpp"
+
+#include "pythonic/numpy/angle_in_deg.hpp"
+#include "pythonic/numpy/angle_in_rad.hpp"
+#include "pythonic/types/assignable.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T>
+ auto angle(T const &t, bool in_deg) ->
+ typename assignable<decltype(functor::angle_in_rad()(t))>::type
+ // assignable to find a common type between the two expression templates
+ {
+ if (in_deg)
+ return functor::angle_in_deg()(t);
+ else
+ return functor::angle_in_rad()(t);
+ }
+
+ // Numpy_expr can be use if only the first argument is given.
+ template <class T>
+ auto angle(T const &t) -> decltype(functor::angle_in_rad()(t))
+ {
+ return functor::angle_in_rad()(t);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/angle_in_deg.hpp b/contrib/python/pythran/pythran/pythonic/numpy/angle_in_deg.hpp
new file mode 100644
index 00000000000..a77eb7e1b92
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/angle_in_deg.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_NUMPY_ANGLEINDEG_HPP
+#define PYTHONIC_NUMPY_ANGLEINDEG_HPP
+
+#include "pythonic/include/numpy/angle_in_deg.hpp"
+
+#include "pythonic/numpy/angle_in_rad.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/numpy/pi.hpp"
+
+/* NOTE: angle_in_deg is not part of the official Numpy API,
+ * this file is here only to split the angle function in two parts
+ */
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME angle_in_deg
+#define NUMPY_NARY_FUNC_SYM wrapper::angle_in_deg
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/angle_in_rad.hpp b/contrib/python/pythran/pythran/pythonic/numpy/angle_in_rad.hpp
new file mode 100644
index 00000000000..7e955d1a9fa
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/angle_in_rad.hpp
@@ -0,0 +1,36 @@
+#ifndef PYTHONIC_NUMPY_ANGLEINRAD_HPP
+#define PYTHONIC_NUMPY_ANGLEINRAD_HPP
+
+#include "pythonic/include/numpy/angle_in_rad.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/numpy/arctan.hpp"
+#include "pythonic/numpy/pi.hpp"
+
+/* NOTE: angle_in_rad is not part of the official Numpy API,
+ * this file is here only to split the angle function in two parts
+ */
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T>
+ auto angle_in_rad(T const &t)
+ -> decltype(std::atan2(std::imag(t), std::real(t)))
+ {
+ return std::atan2(std::imag(t), std::real(t));
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME angle_in_rad
+#define NUMPY_NARY_FUNC_SYM wrapper::angle_in_rad
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/any.hpp b/contrib/python/pythran/pythran/pythonic/numpy/any.hpp
new file mode 100644
index 00000000000..9f15c2d961b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/any.hpp
@@ -0,0 +1,99 @@
+#ifndef PYTHONIC_NUMPY_ANY_HPP
+#define PYTHONIC_NUMPY_ANY_HPP
+
+#include "pythonic/include/numpy/any.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/builtins/ValueError.hpp"
+#include "pythonic/numpy/add.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ bool _any(E const &e, utils::int_<1>)
+ {
+ return std::any_of(e.begin(), e.end(),
+ [](typename E::dtype elt) -> bool { return elt; });
+ }
+
+ template <class E, size_t N>
+ bool _any(E const &e, utils::int_<N>)
+ {
+ for (auto &&elt : e)
+ if (_any(elt, utils::int_<N - 1>())) {
+ return true;
+ }
+ return false;
+ }
+
+ template <class E>
+ typename std::enable_if<types::is_numexpr_arg<E>::value, bool>::type
+ any(E const &expr, types::none_type)
+ {
+ return _any(expr, utils::int_<E::value>());
+ }
+
+ template <class E>
+ typename std::enable_if<
+ std::is_scalar<E>::value || types::is_complex<E>::value, bool>::type
+ any(E const &expr, types::none_type)
+ {
+ return expr;
+ }
+
+ template <class E>
+ auto any(E const &array, long axis) ->
+ typename std::enable_if<std::is_scalar<E>::value ||
+ types::is_complex<E>::value,
+ decltype(any(array))>::type
+ {
+ if (axis != 0)
+ throw types::ValueError("axis out of bounds");
+ return any(array);
+ }
+
+ template <class E>
+ auto any(E const &array, long axis) ->
+ typename std::enable_if<E::value == 1, decltype(any(array))>::type
+ {
+ if (axis != 0)
+ throw types::ValueError("axis out of bounds");
+ return any(array);
+ }
+
+ template <class E>
+ typename std::enable_if<
+ E::value != 1,
+ types::ndarray<typename E::dtype, types::array<long, E::value - 1>>>::type
+ any(E const &array, long axis)
+ {
+ constexpr long N = E::value;
+ using T = typename E::dtype;
+ if (axis < 0 || axis >= long(N))
+ throw types::ValueError("axis out of bounds");
+ if (axis == 0) {
+ types::array<long, N> shp;
+ shp[0] = 1;
+ sutils::copy_shape<1, 0>(shp, array, utils::make_index_sequence<N - 1>());
+ types::ndarray<bool, types::array<long, N>> out(shp, false);
+ return std::accumulate(array.begin(), array.end(), *out.begin(),
+ numpy::functor::add());
+ } else {
+ types::array<long, N - 1> shp;
+ sutils::copy_shape<0, 0>(shp, array, utils::make_index_sequence<N - 1>());
+ types::ndarray<bool, types::array<long, N - 1>> anyy(shp, builtins::None);
+ std::transform(
+ array.begin(), array.end(), anyy.begin(),
+ [=](types::ndarray<T, types::array<long, N - 1>> const &other) {
+ return any(other, axis - 1);
+ });
+ return anyy;
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/append.hpp b/contrib/python/pythran/pythran/pythonic/numpy/append.hpp
new file mode 100644
index 00000000000..c2d4590a72d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/append.hpp
@@ -0,0 +1,61 @@
+#ifndef PYTHONIC_NUMPY_APPEND_HPP
+#define PYTHONIC_NUMPY_APPEND_HPP
+
+#include "pythonic/include/numpy/append.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS, class F>
+ typename std::enable_if<
+ !types::is_dtype<F>::value,
+ types::ndarray<
+ typename __combined<T, typename types::dtype_of<F>::type>::type,
+ types::pshape<long>>>::type
+ append(types::ndarray<T, pS> const &nto, F const &data)
+ {
+ auto ndata = numpy::functor::asarray{}(data);
+ long nsize = nto.flat_size() + ndata.flat_size();
+ types::ndarray<
+ typename __combined<T, typename types::dtype_of<F>::type>::type,
+ types::pshape<long>>
+ out(types::pshape<long>(nsize), builtins::None);
+ auto out_back = std::copy(nto.fbegin(), nto.fend(), out.fbegin());
+ std::copy(ndata.fbegin(), ndata.fend(), out_back);
+ return out;
+ }
+ template <class T, class pS, class F>
+ typename std::enable_if<
+ types::is_dtype<F>::value,
+ types::ndarray<
+ typename __combined<T, typename types::dtype_of<F>::type>::type,
+ types::pshape<long>>>::type
+ append(types::ndarray<T, pS> const &nto, F const &data)
+ {
+ long nsize = nto.flat_size() + 1;
+ types::ndarray<
+ typename __combined<T, typename types::dtype_of<F>::type>::type,
+ types::pshape<long>>
+ out(types::pshape<long>(nsize), builtins::None);
+ auto out_back = std::copy(nto.fbegin(), nto.fend(), out.fbegin());
+ *out_back = data;
+ return out;
+ }
+
+ template <class T, class F>
+ types::ndarray<typename __combined<typename types::dtype_of<T>::type,
+ typename types::dtype_of<F>::type>::type,
+ types::pshape<long>>
+ append(T const &to, F const &data)
+ {
+ return append(numpy::functor::asarray{}(to), data);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/arange.hpp b/contrib/python/pythran/pythran/pythonic/numpy/arange.hpp
new file mode 100644
index 00000000000..14e1d0ad445
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/arange.hpp
@@ -0,0 +1,38 @@
+#ifndef PYTHONIC_NUMPY_ARANGE_HPP
+#define PYTHONIC_NUMPY_ARANGE_HPP
+
+#include "pythonic/include/numpy/arange.hpp"
+
+#include "pythonic/operator_/pos.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class U, class S, class dtype>
+ types::numpy_expr<pythonic::operator_::functor::pos,
+ details::arange_index<typename dtype::type>>
+ arange(T begin, U end, S step, dtype d)
+ {
+ using R = typename dtype::type;
+ long size;
+ if (std::is_integral<R>::value)
+ size = std::max(R(0), R((end - begin + step - 1) / step));
+ else
+ size = std::max(R(0), R(std::ceil((end - begin) / step)));
+ return {details::arange_index<R>{(R)begin, (R)step, size}};
+ }
+
+ template <class T>
+ types::numpy_expr<pythonic::operator_::functor::pos,
+ details::arange_index<typename types::dtype_t<T>::type>>
+ arange(T end)
+ {
+ return arange<T, T, T, types::dtype_t<T>>(T(0), end);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/arccos.hpp b/contrib/python/pythran/pythran/pythonic/numpy/arccos.hpp
new file mode 100644
index 00000000000..a1d827daa53
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/arccos.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_NUMPY_ARCCOS_HPP
+#define PYTHONIC_NUMPY_ARCCOS_HPP
+
+#include "pythonic/include/numpy/arccos.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME arccos
+#define NUMPY_NARY_FUNC_SYM xsimd::acos
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/arccosh.hpp b/contrib/python/pythran/pythran/pythonic/numpy/arccosh.hpp
new file mode 100644
index 00000000000..b915e8bbb5b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/arccosh.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_NUMPY_ARCCOSH_HPP
+#define PYTHONIC_NUMPY_ARCCOSH_HPP
+
+#include "pythonic/include/numpy/arccosh.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME arccosh
+#define NUMPY_NARY_FUNC_SYM xsimd::acosh
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/arcsin.hpp b/contrib/python/pythran/pythran/pythonic/numpy/arcsin.hpp
new file mode 100644
index 00000000000..cbec9c23865
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/arcsin.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_NUMPY_ARCSIN_HPP
+#define PYTHONIC_NUMPY_ARCSIN_HPP
+
+#include "pythonic/include/numpy/arcsin.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME arcsin
+#define NUMPY_NARY_FUNC_SYM xsimd::asin
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/arcsinh.hpp b/contrib/python/pythran/pythran/pythonic/numpy/arcsinh.hpp
new file mode 100644
index 00000000000..96edf5d2526
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/arcsinh.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_NUMPY_ARCSINH_HPP
+#define PYTHONIC_NUMPY_ARCSINH_HPP
+
+#include "pythonic/include/numpy/arcsinh.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME arcsinh
+#define NUMPY_NARY_FUNC_SYM xsimd::asinh
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/arctan.hpp b/contrib/python/pythran/pythran/pythonic/numpy/arctan.hpp
new file mode 100644
index 00000000000..c7239fcf461
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/arctan.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_NUMPY_ARCTAN_HPP
+#define PYTHONIC_NUMPY_ARCTAN_HPP
+
+#include "pythonic/include/numpy/arctan.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME arctan
+#define NUMPY_NARY_FUNC_SYM xsimd::atan
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/arctan2/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/arctan2/accumulate.hpp
new file mode 100644
index 00000000000..39b9f3a93ec
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/arctan2/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_ARCTAN2_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_ARCTAN2_ACCUMULATE_HPP
+
+#define UFUNC_NAME arctan2
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/arctanh.hpp b/contrib/python/pythran/pythran/pythonic/numpy/arctanh.hpp
new file mode 100644
index 00000000000..0b9d267dca5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/arctanh.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_NUMPY_ARCTANH_HPP
+#define PYTHONIC_NUMPY_ARCTANH_HPP
+
+#include "pythonic/include/numpy/arctanh.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME arctanh
+#define NUMPY_NARY_FUNC_SYM xsimd::atanh
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/argmax.hpp b/contrib/python/pythran/pythran/pythonic/numpy/argmax.hpp
new file mode 100644
index 00000000000..a2887c16304
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/argmax.hpp
@@ -0,0 +1,47 @@
+#ifndef PYTHONIC_NUMPY_ARGMAX_HPP
+#define PYTHONIC_NUMPY_ARGMAX_HPP
+
+#include "pythonic/include/numpy/argmax.hpp"
+#include "pythonic/numpy/argminmax.hpp"
+#include "pythonic/numpy/maximum.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ struct argmax_op {
+ using op = functor::maximum;
+ using expr_type = E;
+ static typename E::dtype constexpr limit()
+ {
+ return std::numeric_limits<typename E::dtype>::lowest();
+ }
+ template <class T>
+ static T elements(T first, T last)
+ {
+ return std::max_element(first, last);
+ }
+ template <class T>
+ static bool value(T self, T other)
+ {
+ return self > other;
+ }
+ };
+
+ template <class E>
+ long argmax(E const &expr)
+ {
+ return argminmax<argmax_op<E>>(expr);
+ }
+
+ template <class E>
+ types::ndarray<long, types::array<long, E::value - 1>> argmax(E const &expr,
+ long axis)
+ {
+ return argminmax<argmax_op<E>>(expr, axis);
+ }
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/argmin.hpp b/contrib/python/pythran/pythran/pythonic/numpy/argmin.hpp
new file mode 100644
index 00000000000..35652a89f21
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/argmin.hpp
@@ -0,0 +1,48 @@
+#ifndef PYTHONIC_NUMPY_ARGMIN_HPP
+#define PYTHONIC_NUMPY_ARGMIN_HPP
+
+#include "pythonic/include/numpy/argmin.hpp"
+
+#include "pythonic/numpy/argminmax.hpp"
+#include "pythonic/numpy/minimum.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ struct argmin_op {
+ using op = functor::minimum;
+ using expr_type = E;
+ static typename E::dtype constexpr limit()
+ {
+ return std::numeric_limits<typename E::dtype>::max();
+ }
+ template <class T>
+ static T elements(T first, T last)
+ {
+ return std::min_element(first, last);
+ }
+ template <class T>
+ static bool value(T self, T other)
+ {
+ return self < other;
+ }
+ };
+
+ template <class E>
+ long argmin(E const &expr)
+ {
+ return argminmax<argmin_op<E>>(expr);
+ }
+
+ template <class E>
+ types::ndarray<long, types::array<long, E::value - 1>> argmin(E const &expr,
+ long axis)
+ {
+ return argminmax<argmin_op<E>>(expr, axis);
+ }
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/argminmax.hpp b/contrib/python/pythran/pythran/pythonic/numpy/argminmax.hpp
new file mode 100644
index 00000000000..c1286d6348b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/argminmax.hpp
@@ -0,0 +1,281 @@
+#ifndef PYTHONIC_NUMPY_ARGMINMAX_HPP
+#define PYTHONIC_NUMPY_ARGMINMAX_HPP
+
+#include "pythonic/builtins/ValueError.hpp"
+#include "pythonic/numpy/asarray.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace details
+ {
+ template <class P, size_t... Is>
+ P iota(utils::index_sequence<Is...>)
+ {
+ return {static_cast<typename P::value_type>(Is)...};
+ }
+
+ template <class P>
+ P iota()
+ {
+ return iota<P>(utils::make_index_sequence<P::size>());
+ }
+ } // namespace details
+ template <class Op, class E, class T>
+ long _argminmax_seq(E const &elts, T &minmax_elts)
+ {
+ long index = 0;
+ long res = -1;
+ for (auto const &elt : elts) {
+ if (Op::value(elt, minmax_elts)) {
+ minmax_elts = elt;
+ res = index;
+ }
+ ++index;
+ }
+
+ return res;
+ }
+ template <class Op, class E, class T>
+#ifdef USE_XSIMD
+ typename std::enable_if<
+ !E::is_vectorizable ||
+ !types::is_vector_op<typename Op::op, T, T>::value ||
+ std::is_same<typename E::dtype, bool>::value,
+ long>::type
+#else
+ long
+#endif
+ _argminmax(E const &elts, T &minmax_elts, utils::int_<1>)
+ {
+ return _argminmax_seq<Op>(elts, minmax_elts);
+ }
+
+ template <class Op, class E, class T, class... Indices>
+ std::tuple<long, long> _argminmax_fast(E const &elts, T &minmax_elts,
+ long current_pos, utils::int_<1>,
+ Indices... indices)
+ {
+ long res = -1;
+ long n = elts.template shape<std::decay<E>::type::value - 1>();
+ for (long i = 0; i < n; ++i) {
+ auto elt = elts.load(indices..., i);
+ if (Op::value(elt, minmax_elts)) {
+ minmax_elts = elt;
+ res = current_pos + i;
+ }
+ }
+
+ return std::make_tuple(res, current_pos + n);
+ }
+
+#ifdef USE_XSIMD
+ template <class Op, class E, class T>
+ typename std::enable_if<
+ E::is_vectorizable && types::is_vector_op<typename Op::op, T, T>::value &&
+ !std::is_same<typename E::dtype, bool>::value,
+ long>::type
+ _argminmax(E const &elts, T &minmax_elts, utils::int_<1>)
+ {
+ using vT = xsimd::batch<T>;
+ using iT = xsimd::as_integer_t<T>;
+ static const size_t vN = vT::size;
+ const long n = elts.size();
+ if (n >= std::numeric_limits<iT>::max()) {
+ return _argminmax_seq<Op>(elts, minmax_elts);
+ }
+
+ auto viter = types::vectorizer_nobroadcast::vbegin(elts),
+ vend = types::vectorizer_nobroadcast::vend(elts);
+
+ const long bound = std::distance(viter, vend);
+ long minmax_index = -1;
+ if (bound > 0) {
+ auto vacc = *viter;
+ alignas(sizeof(vT)) iT iota[vN] = {0};
+ for (long i = 0; i < (long)vN; ++i)
+ iota[i] = i;
+ xsimd::batch<iT> curr = xsimd::load_aligned(iota);
+ xsimd::batch<iT> indices = curr;
+ xsimd::batch<iT> step(vN);
+
+ for (++viter, curr += step; viter != vend; ++viter, curr += step) {
+ auto c = *viter;
+ // In order to keep the first element that matches the condition,
+ // we compare to the previous vacc and select indices based on that
+ // mask.
+ auto prev_vacc = vacc;
+ vacc = typename Op::op{}(vacc, c);
+ auto mask = xsimd::batch_bool_cast<iT>(prev_vacc != vacc);
+ indices = xsimd::select(mask, curr, indices);
+ }
+
+ alignas(sizeof(vT)) T stored[vN];
+ vacc.store_aligned(&stored[0]);
+ alignas(sizeof(vT)) long indexed[vN];
+ indices.store_aligned(&indexed[0]);
+
+ for (size_t j = 0; j < vN; ++j) {
+ if (Op::value(stored[j], minmax_elts)) {
+ minmax_elts = stored[j];
+ minmax_index = indexed[j];
+ }
+ }
+ }
+ auto iter = elts.begin() + bound * vN;
+
+ for (long i = bound * vN; i < n; ++i, ++iter) {
+ if (Op::value(*iter, minmax_elts)) {
+ minmax_elts = *iter;
+ minmax_index = i;
+ }
+ }
+ return minmax_index;
+ }
+#endif
+
+ template <class Op, class E, size_t N, class T>
+ long _argminmax(E const &elts, T &minmax_elts, utils::int_<N>)
+ {
+ long current_pos = 0;
+ long current_minmaxarg = 0;
+ for (auto &&elt : elts) {
+ long v = _argminmax<Op>(elt, minmax_elts, utils::int_<N - 1>());
+ if (v >= 0)
+ current_minmaxarg = current_pos + v;
+ current_pos += elt.flat_size();
+ }
+ return current_minmaxarg;
+ }
+ template <class Op, class E, size_t N, class T, class... Indices>
+ typename std::enable_if<N != 1, std::tuple<long, long>>::type
+ _argminmax_fast(E const &elts, T &minmax_elts, long current_pos,
+ utils::int_<N>, Indices... indices)
+ {
+ long current_minmaxarg = 0;
+ for (long i = 0, n = elts.template shape<std::decay<E>::type::value - N>();
+ i < n; ++i) {
+ long v;
+ std::tie(v, current_pos) = _argminmax_fast<Op>(
+ elts, minmax_elts, current_pos, utils::int_<N - 1>(), indices..., i);
+ if (v >= 0)
+ current_minmaxarg = v;
+ }
+ return std::make_tuple(current_minmaxarg, current_pos);
+ }
+
+ template <class Op, class E>
+ long argminmax(E const &expr)
+ {
+ if (!expr.flat_size())
+ throw types::ValueError("empty sequence");
+ using elt_type = typename E::dtype;
+ elt_type argminmax_value = Op::limit();
+#ifndef USE_XSIMD
+ if (utils::no_broadcast_ex(expr)) {
+ return std::get<0>(_argminmax_fast<Op>(expr, argminmax_value, 0,
+ utils::int_<E::value>()));
+ } else
+#endif
+ return _argminmax<Op>(expr, argminmax_value, utils::int_<E::value>());
+ }
+
+ template <class Op, size_t Dim, size_t Axis, class T, class E, class V>
+ void _argminmax_tail(T &&out, E const &expr, long curr, V &&curr_minmax,
+ std::integral_constant<size_t, 0>)
+ {
+ if (Op::value(expr, curr_minmax)) {
+ out = curr;
+ curr_minmax = expr;
+ }
+ }
+
+ template <class Op, size_t Dim, size_t Axis, class T, class E, class V,
+ size_t N>
+ typename std::enable_if<Axis != (Dim - N), void>::type
+ _argminmax_tail(T &&out, E const &expr, long curr, V &&curr_minmax,
+ std::integral_constant<size_t, N>)
+ {
+ static_assert(N >= 1, "specialization ok");
+ long i = 0;
+ for (auto &&elt : expr) {
+ _argminmax_tail<Op, Dim, Axis>(out.fast(i), elt, curr,
+ curr_minmax.fast(i),
+ std::integral_constant<size_t, N - 1>());
+ ++i;
+ }
+ }
+
+ template <class Op, size_t Dim, size_t Axis, class T, class E>
+ typename std::enable_if<Axis == (Dim - 1), void>::type
+ _argminmax_head(T &&out, E const &expr, std::integral_constant<size_t, 1>)
+ {
+ typename E::dtype val = Op::limit();
+ long i = 0;
+ for (auto &&elt : expr)
+ _argminmax_tail<Op, Dim, Axis>(out, elt, i++, val,
+ std::integral_constant<size_t, 0>());
+ }
+
+ template <class Op, size_t Dim, size_t Axis, class T, class E, size_t N>
+ typename std::enable_if<Axis == (Dim - N), void>::type
+ _argminmax_head(T &&out, E const &expr, std::integral_constant<size_t, N>)
+ {
+ static_assert(N > 1, "specialization ok");
+ types::ndarray<typename E::dtype, types::array<long, N - 1>> val{
+ sutils::getshape(out), Op::limit()};
+ long i = 0;
+ for (auto &&elt : expr) {
+ _argminmax_tail<Op, Dim, Axis>(out, elt, i++, val,
+ std::integral_constant<size_t, N - 1>());
+ }
+ }
+
+ template <class Op, size_t Dim, size_t Axis, class T, class E, size_t N>
+ typename std::enable_if<Axis != (Dim - N), void>::type
+ _argminmax_head(T &&out, E const &expr, std::integral_constant<size_t, N>)
+ {
+ static_assert(N >= 1, "specialization ok");
+ auto out_iter = out.begin();
+ for (auto &&elt : expr) {
+ _argminmax_head<Op, Dim, Axis>(*out_iter, elt,
+ std::integral_constant<size_t, N - 1>());
+ ++out_iter;
+ }
+ }
+
+ template <class Op, size_t N, class T, class E, size_t... Axis>
+ void _argminmax_pick_axis(long axis, T &&out, E const &expr,
+ utils::index_sequence<Axis...>)
+ {
+ (void)std::initializer_list<bool>{
+ ((Axis == axis) && (_argminmax_head<Op, N, Axis>(
+ out, expr, std::integral_constant<size_t, N>()),
+ true))...};
+ }
+
+ template <class Op, class E>
+ types::ndarray<long, types::array<long, E::value - 1>>
+ argminmax(E const &array, long axis)
+ {
+ if (axis < 0)
+ axis += E::value;
+ if (axis < 0 || size_t(axis) >= E::value)
+ throw types::ValueError("axis out of bounds");
+ auto shape = sutils::getshape(array);
+ types::array<long, E::value - 1> shp;
+ auto next = std::copy(shape.begin(), shape.begin() + axis, shp.begin());
+ std::copy(shape.begin() + axis + 1, shape.end(), next);
+ types::ndarray<long, types::array<long, E::value - 1>> out{shp,
+ builtins::None};
+ _argminmax_pick_axis<Op, E::value>(axis, out, array,
+ utils::make_index_sequence<E::value>());
+ return out;
+ }
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/argsort.hpp b/contrib/python/pythran/pythran/pythonic/numpy/argsort.hpp
new file mode 100644
index 00000000000..8ed208e9ac4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/argsort.hpp
@@ -0,0 +1,95 @@
+#ifndef PYTHONIC_NUMPY_ARGSORT_HPP
+#define PYTHONIC_NUMPY_ARGSORT_HPP
+
+#include "pythonic/include/numpy/argsort.hpp"
+#include "pythonic/numpy/ndarray/sort.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ types::ndarray<long, types::array<long, 1>> argsort(E const &expr,
+ types::none_type, types::none_type)
+ {
+ auto out = functor::array{}(expr).flat();
+ return argsort(out);
+ }
+
+ template <class T, class pS, class Sorter>
+ types::ndarray<long, pS> _argsort(types::ndarray<T, pS> const &a, long axis, Sorter sorter)
+ {
+ constexpr auto N = std::tuple_size<pS>::value;
+ if (axis < 0)
+ axis += N;
+
+ long const flat_size = a.flat_size();
+ types::ndarray<long, pS> indices(a._shape, builtins::None);
+ if (axis == N - 1) {
+ size_t step = a.template shape<N - 1>();
+
+ auto a_base = a.fbegin();
+ for (long *iter_indices = indices.buffer,
+ *end_indices = indices.buffer + flat_size;
+ iter_indices != end_indices; iter_indices += step, a_base += step) {
+ // fill with the original indices
+ std::iota(iter_indices, iter_indices + step, 0L);
+ // sort the index using the value from a
+ sorter(iter_indices, iter_indices + step,
+ [a_base](long i1, long i2) { return a_base[i1] < a_base[i2]; });
+ }
+ } else {
+ auto out_shape = sutils::getshape(a);
+ const long step =
+ std::accumulate(out_shape.begin() + axis, out_shape.end(), 1L,
+ std::multiplies<long>());
+ long const buffer_size = out_shape[axis];
+ const long stepper = step / out_shape[axis];
+ const long n = flat_size / out_shape[axis];
+ long ith = 0, nth = 0;
+
+ long *buffer = utils::allocate<long>(buffer_size);
+ long *buffer_start = buffer, *buffer_end = buffer + buffer_size;
+ std::iota(buffer_start, buffer_end, 0L);
+ for (long i = 0; i < n; i++) {
+ auto a_base = a.fbegin() + ith;
+ sorter(buffer, buffer + buffer_size,
+ [a_base, stepper](long i1, long i2) {
+ return a_base[i1 * stepper] < a_base[i2 * stepper];
+ });
+
+ for (long j = 0; j < buffer_size; ++j)
+ indices.buffer[ith + j * stepper] = buffer[j];
+
+ ith = step;
+ if (ith >= flat_size) {
+ ith = ++nth;
+ }
+ }
+ utils::deallocate(buffer);
+ }
+ return indices;
+ }
+
+ template <class T, class pS>
+ types::ndarray<long, pS> argsort(types::ndarray<T, pS> const &a, long axis, types::none_type) {
+ return _argsort(a, axis, ndarray::quicksorter());
+ }
+
+ template <class T, class pS>
+ types::ndarray<long, pS> argsort(types::ndarray<T, pS> const &a, long axis, types::str const& kind)
+ {
+ if (kind == "mergesort")
+ return _argsort(a, axis, ndarray::mergesorter());
+ else if (kind == "heapsort")
+ return _argsort(a, axis, ndarray::heapsorter());
+ else if (kind == "stable")
+ return _argsort(a, axis, ndarray::stablesorter());
+ return _argsort(a, axis, ndarray::quicksorter());
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(argsort);
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/argwhere.hpp b/contrib/python/pythran/pythran/pythonic/numpy/argwhere.hpp
new file mode 100644
index 00000000000..30186da5d30
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/argwhere.hpp
@@ -0,0 +1,46 @@
+#ifndef PYTHONIC_NUMPY_ARGWHERE_HPP
+#define PYTHONIC_NUMPY_ARGWHERE_HPP
+
+#include "pythonic/include/numpy/argwhere.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ typename types::ndarray<long, types::array<long, 2>> argwhere(E const &expr)
+ {
+ constexpr long N = E::value;
+ auto arr = asarray(expr);
+ long sz = arr.flat_size();
+ auto eshape = sutils::getshape(arr);
+
+ utils::shared_ref<types::raw_array<long>> buffer(sz *
+ N); // too much memory used
+ long *buffer_iter = buffer->data;
+
+ long real_sz = 0;
+ auto iter = arr.fbegin();
+ for (long i = 0; i < sz; ++i, ++iter) {
+ if (*iter) {
+ ++real_sz;
+ long mult = 1;
+ for (long j = N - 1; j > 0; j--) {
+ buffer_iter[j] = (i / mult) % eshape[j];
+ mult *= eshape[j];
+ }
+ buffer_iter[0] = i / mult;
+ buffer_iter += N;
+ }
+ }
+ types::array<long, 2> shape = {real_sz, N};
+ return {buffer, shape};
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/around.hpp b/contrib/python/pythran/pythran/pythonic/numpy/around.hpp
new file mode 100644
index 00000000000..1b467e523bb
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/around.hpp
@@ -0,0 +1,63 @@
+#ifndef PYTHONIC_NUMPY_AROUND_HPP
+#define PYTHONIC_NUMPY_AROUND_HPP
+
+#include "pythonic/include/numpy/around.hpp"
+
+#include "pythonic/numpy/rint.hpp"
+#include "pythonic/numpy/power.hpp"
+#include "pythonic/numpy/asarray.hpp"
+#include "pythonic/numpy/floor_divide.hpp"
+#include "pythonic/numpy/float64.hpp"
+#include "pythonic/numpy/multiply.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ // fast path
+ template <class E>
+ auto around(E &&a) -> decltype(functor::rint{}(std::forward<E>(a)))
+ {
+ return functor::rint{}(std::forward<E>(a));
+ }
+
+ // generic floating point version, pure numpy_expr
+ template <class E>
+ auto around(E &&a, long decimals) -> typename std::enable_if<
+ !std::is_integral<
+ typename types::dtype_of<typename std::decay<E>::type>::type>::value,
+ decltype(functor::rint{}(functor::multiply{}(
+ std::forward<E>(a),
+ std::declval<typename types::dtype_of<
+ typename std::decay<E>::type>::type>())) /
+ std::declval<typename types::dtype_of<
+ typename std::decay<E>::type>::type>())>::type
+ {
+ typename types::dtype_of<typename std::decay<E>::type>::type const fact =
+ functor::power{}(10., decimals);
+ return functor::rint{}(functor::multiply{}(std::forward<E>(a), fact)) /
+ fact;
+ }
+
+ // the integer version is only relevant when decimals < 0
+ template <class E>
+ auto around(E &&a, long decimals) -> typename std::enable_if<
+ std::is_integral<
+ typename types::dtype_of<typename std::decay<E>::type>::type>::value,
+ decltype(numpy::functor::floor_divide{}(
+ functor::float64{}(std::forward<E>(a)),
+ std::declval<typename types::dtype_of<
+ typename std::decay<E>::type>::type>()) *
+ std::declval<typename types::dtype_of<
+ typename std::decay<E>::type>::type>())>::type
+ {
+ typename types::dtype_of<typename std::decay<E>::type>::type const fact =
+ functor::power{}(10L, std::max(0L, -decimals));
+ return pythonic::numpy::functor::floor_divide{}(
+ functor::float64{}(std::forward<E>(a)), fact) *
+ fact;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/array2string.hpp b/contrib/python/pythran/pythran/pythonic/numpy/array2string.hpp
new file mode 100644
index 00000000000..d27984a8a16
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/array2string.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_NUMPY_ARRAY2STRING_HPP
+#define PYTHONIC_NUMPY_ARRAY2STRING_HPP
+
+#include "pythonic/include/numpy/array2string.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/str.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ types::str array2string(E &&a)
+ {
+ std::ostringstream oss;
+ oss << std::forward<E>(a);
+ return oss.str();
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/array_equal.hpp b/contrib/python/pythran/pythran/pythonic/numpy/array_equal.hpp
new file mode 100644
index 00000000000..606444c6756
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/array_equal.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_NUMPY_ARRAYEQUAL_HPP
+#define PYTHONIC_NUMPY_ARRAYEQUAL_HPP
+
+#include "pythonic/include/numpy/array_equal.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/numpy/all.hpp"
+#include "pythonic/numpy/equal.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class U, class V>
+ bool array_equal(U const &u, V const &v)
+ {
+ if (sutils::getshape(u) == sutils::getshape(v))
+ return all(functor::equal{}(u, v));
+ return false;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/array_equiv.hpp b/contrib/python/pythran/pythran/pythonic/numpy/array_equiv.hpp
new file mode 100644
index 00000000000..aa576deb69c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/array_equiv.hpp
@@ -0,0 +1,51 @@
+#ifndef PYTHONIC_NUMPY_ARRAYEQUIV_HPP
+#define PYTHONIC_NUMPY_ARRAYEQUIV_HPP
+
+#include "pythonic/include/numpy/array_equiv.hpp"
+
+#include "pythonic/numpy/array_equal.hpp"
+#include "pythonic/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace
+ {
+ template <class I0, class U>
+ bool _array_equiv(I0 vbegin, I0 vend, U const &uu)
+ {
+ for (; vbegin != vend; ++vbegin)
+ if (!array_equiv(uu, *vbegin))
+ return false;
+ return true;
+ }
+ }
+
+ template <class U, class V>
+ typename std::enable_if<U::value == V::value, bool>::type
+ array_equiv(U const &u, V const &v)
+ {
+ return array_equal(u, v);
+ }
+
+ template <class U, class V>
+ typename std::enable_if <
+ U::value<V::value, bool>::type array_equiv(U const &u, V const &v)
+ {
+ if (v.flat_size() % u.flat_size() == 0)
+ // requires allocation for u' as it is used multiple times.
+ return _array_equiv(v.begin(), v.end(), asarray(u));
+ return false;
+ }
+
+ template <class U, class V>
+ typename std::enable_if<(U::value > V::value), bool>::type
+ array_equiv(U const &u, V const &v)
+ {
+ return array_equiv(v, u);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/array_split.hpp b/contrib/python/pythran/pythran/pythonic/numpy/array_split.hpp
new file mode 100644
index 00000000000..933a9fafa7c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/array_split.hpp
@@ -0,0 +1,63 @@
+#ifndef PYTHONIC_NUMPY_ARRAYSPLIT_HPP
+#define PYTHONIC_NUMPY_ARRAYSPLIT_HPP
+
+#include "pythonic/include/numpy/array_split.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ types::list<typename assignable<
+ decltype(std::declval<E>()[types::fast_contiguous_slice()])>::type>
+ array_split(E const &a, long nb_split)
+ {
+ long sz = a.template shape<0>();
+ long n = (sz + nb_split - 1) / nb_split;
+ long end = n * nb_split;
+ long nb_full_split = nb_split;
+ if (end != sz)
+ nb_full_split -= (end - sz);
+ types::list<typename assignable<
+ decltype(std::declval<E>()[types::fast_contiguous_slice()])>::type>
+ out(nb_split);
+
+ long index = 0;
+ for (long i = 0; i < nb_full_split; ++i, index += n)
+ out[i] = a[types::fast_contiguous_slice(index, index + n)];
+ for (long i = nb_full_split; i < nb_split; ++i, index += (n - 1))
+ out[i] = a[types::fast_contiguous_slice(index, index + n - 1)];
+
+ return out;
+ }
+
+ template <class E, class I>
+ typename std::enable_if<
+ types::is_iterable<I>::value,
+ types::list<typename assignable<
+ decltype(std::declval<E>()[types::fast_contiguous_slice()])>::type>>::
+ type
+ array_split(E const &a, I const &split_mask)
+ {
+ long sz = a.template shape<0>();
+ types::list<typename assignable<
+ decltype(std::declval<E>()[types::fast_contiguous_slice()])>::type>
+ out(1 + split_mask.flat_size());
+ long index = 0;
+ auto inserter = out.begin();
+ for (auto next_index : split_mask) {
+ *inserter++ = a[types::fast_contiguous_slice(index, next_index)];
+ index = next_index;
+ }
+ *inserter = a[types::fast_contiguous_slice(index, sz)];
+ return out;
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(array_split);
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/array_str.hpp b/contrib/python/pythran/pythran/pythonic/numpy/array_str.hpp
new file mode 100644
index 00000000000..9cbaa6aa99b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/array_str.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_ARRAYSTR_HPP
+#define PYTHONIC_NUMPY_ARRAYSTR_HPP
+
+#include "pythonic/include/numpy/array_str.hpp"
+#include "pythonic/numpy/array2string.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/asarray_chkfinite.hpp b/contrib/python/pythran/pythran/pythonic/numpy/asarray_chkfinite.hpp
new file mode 100644
index 00000000000..78df26bcf55
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/asarray_chkfinite.hpp
@@ -0,0 +1,33 @@
+#ifndef PYTHONIC_NUMPY_ASARRAYCHKFINITE_HPP
+#define PYTHONIC_NUMPY_ASARRAYCHKFINITE_HPP
+
+#include "pythonic/include/numpy/asarray_chkfinite.hpp"
+
+#include "pythonic/builtins/ValueError.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/numpy/isfinite.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace wrapper
+ {
+ template <class I>
+ I asarray_chkfinite(I const &a)
+ {
+ if (!functor::isfinite()(a))
+ throw types::ValueError("array must ! contain infs || NaNs");
+ return a;
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME asarray_chkfinite
+#define NUMPY_NARY_FUNC_SYM wrapper::asarray_chkfinite
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ascontiguousarray.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ascontiguousarray.hpp
new file mode 100644
index 00000000000..c41824e4f4e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ascontiguousarray.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_ASCONTIGUOUSARRAY_HPP
+#define PYTHONIC_NUMPY_ASCONTIGUOUSARRAY_HPP
+
+#include "pythonic/include/numpy/ascontiguousarray.hpp"
+#include "pythonic/numpy/asarray.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/asscalar.hpp b/contrib/python/pythran/pythran/pythonic/numpy/asscalar.hpp
new file mode 100644
index 00000000000..06631f0d62a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/asscalar.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_NUMPY_ASSCALAR_HPP
+#define PYTHONIC_NUMPY_ASSCALAR_HPP
+
+#include "pythonic/include/numpy/asscalar.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/numpy/asarray.hpp"
+#include "pythonic/builtins/ValueError.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ asscalar_result_type<typename E::dtype> asscalar(E const &expr)
+ {
+ if (expr.flat_size() != 1)
+ throw types::ValueError(
+ "can only convert an array of size 1 to a Python scalar");
+ return *asarray(expr).fbegin();
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/atleast_1d.hpp b/contrib/python/pythran/pythran/pythonic/numpy/atleast_1d.hpp
new file mode 100644
index 00000000000..a154d9f7a8e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/atleast_1d.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_NUMPY_ATLEAST1D_HPP
+#define PYTHONIC_NUMPY_ATLEAST1D_HPP
+
+#include "pythonic/include/numpy/atleast_1d.hpp"
+
+#include "pythonic/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T>
+ typename std::enable_if<
+ types::is_dtype<T>::value,
+ types::ndarray<T, types::pshape<std::integral_constant<long, 1>>>>::type
+ atleast_1d(T t)
+ {
+ return {types::pshape<std::integral_constant<long, 1>>(), t};
+ }
+
+ template <class T>
+ auto atleast_1d(T const &t) ->
+ typename std::enable_if<!(types::is_dtype<T>::value),
+ decltype(asarray(t))>::type
+ {
+ return asarray(t);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/atleast_2d.hpp b/contrib/python/pythran/pythran/pythonic/numpy/atleast_2d.hpp
new file mode 100644
index 00000000000..6ff35ab3f40
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/atleast_2d.hpp
@@ -0,0 +1,51 @@
+#ifndef PYTHONIC_NUMPY_ATLEAST2D_HPP
+#define PYTHONIC_NUMPY_ATLEAST2D_HPP
+
+#include "pythonic/include/numpy/atleast_2d.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T>
+ typename std::enable_if<
+ types::is_dtype<T>::value,
+ types::ndarray<T, types::pshape<std::integral_constant<long, 1>,
+ std::integral_constant<long, 1>>>>::type
+ atleast_2d(T t)
+ {
+ return {types::pshape<std::integral_constant<long, 1>,
+ std::integral_constant<long, 1>>(),
+ t};
+ }
+
+ template <class T>
+ auto atleast_2d(T const &t) ->
+ typename std::enable_if < (!types::is_dtype<T>::value) &&
+ T::value<2, types::ndarray<
+ typename T::dtype,
+ types::pshape<std::integral_constant<long, 1>,
+ typename std::tuple_element<
+ 0, typename T::shape_t>::type>>>::type
+ {
+ return t.reshape(types::pshape<
+ std::integral_constant<long, 1>,
+ typename std::tuple_element<0, typename T::shape_t>::type>(
+ std::integral_constant<long, 1>(), t.template shape<0>()));
+ }
+
+ template <class T>
+ auto atleast_2d(T &&t) -> typename std::enable_if<
+ (!types::is_dtype<typename std::remove_cv<
+ typename std::remove_reference<T>::type>::type>::value) &&
+ std::decay<T>::type::value >= 2,
+ decltype(std::forward<T>(t))>::type
+ {
+ return std::forward<T>(t);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/atleast_3d.hpp b/contrib/python/pythran/pythran/pythonic/numpy/atleast_3d.hpp
new file mode 100644
index 00000000000..1ce01bf89b0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/atleast_3d.hpp
@@ -0,0 +1,73 @@
+#ifndef PYTHONIC_NUMPY_ATLEAST3D_HPP
+#define PYTHONIC_NUMPY_ATLEAST3D_HPP
+
+#include "pythonic/include/numpy/atleast_3d.hpp"
+
+#include "pythonic/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T>
+ typename std::enable_if<
+ types::is_dtype<T>::value,
+ types::ndarray<T, types::pshape<std::integral_constant<long, 1>,
+ std::integral_constant<long, 1>,
+ std::integral_constant<long, 1>>>>::type
+ atleast_3d(T t)
+ {
+ return {types::pshape<std::integral_constant<long, 1>,
+ std::integral_constant<long, 1>,
+ std::integral_constant<long, 1>>(),
+ t};
+ }
+
+ template <class T>
+ auto atleast_3d(T const &t) -> typename std::enable_if<
+ (!types::is_dtype<T>::value) && (T::value == 1),
+ types::ndarray<typename T::dtype,
+ types::pshape<std::integral_constant<long, 1>,
+ typename std::tuple_element<
+ 0, typename T::shape_t>::type,
+ std::integral_constant<long, 1>>>>::type
+ {
+ auto r = asarray(t);
+ return r.reshape(
+ types::pshape<std::integral_constant<long, 1>,
+ typename std::tuple_element<0, typename T::shape_t>::type,
+ std::integral_constant<long, 1>>(
+ std::integral_constant<long, 1>(), r.template shape<0>(),
+ std::integral_constant<long, 1>()));
+ }
+
+ template <class T>
+ auto atleast_3d(T const &t) -> typename std::enable_if<
+ (!types::is_dtype<T>::value) && (T::value == 2),
+ types::ndarray<
+ typename T::dtype,
+ types::pshape<
+ typename std::tuple_element<0, typename T::shape_t>::type,
+ typename std::tuple_element<1, typename T::shape_t>::type,
+ std::integral_constant<long, 1>>>>::type
+ {
+ auto r = asarray(t);
+ return r.reshape(
+ types::pshape<typename std::tuple_element<0, typename T::shape_t>::type,
+ typename std::tuple_element<1, typename T::shape_t>::type,
+ std::integral_constant<long, 1>>(
+ r.template shape<0>(), r.template shape<1>(),
+ std::integral_constant<long, 1>()));
+ }
+
+ template <class T>
+ auto atleast_3d(T const &t) ->
+ typename std::enable_if<(!types::is_dtype<T>::value) && T::value >= 3,
+ decltype(asarray(t))>::type
+ {
+ return asarray(t);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/average.hpp b/contrib/python/pythran/pythran/pythonic/numpy/average.hpp
new file mode 100644
index 00000000000..ff01b3a2331
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/average.hpp
@@ -0,0 +1,38 @@
+#ifndef PYTHONIC_NUMPY_AVERAGE_HPP
+#define PYTHONIC_NUMPY_AVERAGE_HPP
+
+#include "pythonic/include/numpy/average.hpp"
+
+#include "pythonic/numpy/asarray.hpp"
+#include "pythonic/numpy/sum.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ auto average(E const &expr, types::none_type const &axis)
+ -> decltype(sum(expr, axis) / 1.)
+ {
+ return sum(expr, axis) / double(expr.flat_size());
+ }
+
+ template <class E>
+ auto average(E const &expr, long axis) -> decltype(sum(expr, axis) / 1.)
+ {
+ auto shape = sutils::getshape(expr);
+ return sum(expr, axis) / double(shape[axis]);
+ }
+
+ template <class E, class W>
+ auto average(E const &expr, types::none_type const &axis, W const &weights)
+ -> decltype(average(expr *asarray(weights) / average(asarray(weights))))
+ {
+ auto aweights = asarray(weights);
+ auto weighted_expr = expr * aweights / average(aweights);
+ return average(weighted_expr);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/base_repr.hpp b/contrib/python/pythran/pythran/pythonic/numpy/base_repr.hpp
new file mode 100644
index 00000000000..a8e5fc64364
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/base_repr.hpp
@@ -0,0 +1,52 @@
+#ifndef PYTHONIC_NUMPY_BASEREPR_HPP
+#define PYTHONIC_NUMPY_BASEREPR_HPP
+
+#include "pythonic/include/numpy/base_repr.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ types::str base_repr(long number, long base, long padding)
+ {
+ types::str res;
+
+ // check that the base if valid
+ if (base < 2 || base > 16) {
+ return res;
+ }
+
+ int const ndigits =
+ (number == 0 ? 1
+ : std::ceil(std::log(std::labs(number)) / std::log(base)));
+ int const effective_padding =
+ padding - ((number == 0) && (padding > 0) ? 1 : 0);
+
+ res.resize(ndigits + effective_padding + (number < 0 ? 1 : 0));
+
+ // Apply negative sign
+ auto it = res.chars().begin();
+ if (number < 0)
+ *it++ = '-';
+
+ // Apply padding
+ std::fill(it, std::next(it, effective_padding), '0');
+
+ auto rit = res.chars().rbegin();
+ long quotient = std::labs(number);
+
+ do {
+ const long tmp = quotient / base;
+ *rit++ = "0123456789ABCDEF"[quotient - (tmp * base)];
+ quotient = tmp;
+ } while (quotient);
+
+ return res;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/binary_repr.hpp b/contrib/python/pythran/pythran/pythonic/numpy/binary_repr.hpp
new file mode 100644
index 00000000000..fcd4b376c30
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/binary_repr.hpp
@@ -0,0 +1,48 @@
+#ifndef PYTHONIC_NUMPY_BINARYREPR_HPP
+#define PYTHONIC_NUMPY_BINARYREPR_HPP
+
+#include "pythonic/include/numpy/binary_repr.hpp"
+
+#include "pythonic/numpy/base_repr.hpp"
+#include "pythonic/utils/allocate.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ inline char *int2bin(long a, char *buffer, int buf_size)
+ {
+ buffer += (buf_size - 1);
+ for (int i = 0; i < buf_size; ++i) {
+ *buffer-- = (a & 1) + '0';
+ a >>= 1;
+ }
+ return buffer;
+ }
+ } // namespace details
+
+ inline types::str binary_repr(long number, types::none_type width)
+ {
+ return base_repr(number, 2);
+ }
+
+ inline types::str binary_repr(long number, long width)
+ {
+ types::str out = binary_repr(std::abs(number));
+ if (number >= 0)
+ return base_repr(number, 2, width - out.size());
+ else {
+ char *mem = utils::allocate<char>(width);
+ details::int2bin(number, mem, width);
+ auto res = types::str(mem, width);
+ return res;
+ }
+ }
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/bincount.hpp b/contrib/python/pythran/pythran/pythonic/numpy/bincount.hpp
new file mode 100644
index 00000000000..2402d0c0966
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/bincount.hpp
@@ -0,0 +1,60 @@
+#ifndef PYTHONIC_NUMPY_BINCOUNT_HPP
+#define PYTHONIC_NUMPY_BINCOUNT_HPP
+
+#include "pythonic/include/numpy/bincount.hpp"
+
+#include "pythonic/numpy/max.hpp"
+#include "pythonic/utils/numpy_conversion.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS>
+ typename std::enable_if<std::tuple_size<pS>::value == 1,
+ types::ndarray<long, types::pshape<long>>>::type
+ bincount(types::ndarray<T, pS> const &expr, types::none_type weights,
+ types::none<long> minlength)
+ {
+ long length = 0;
+ if (minlength)
+ length = (long)minlength;
+ length = std::max<long>(length, 1 + max(expr));
+ types::ndarray<long, types::pshape<long>> out(types::pshape<long>(length),
+ 0L);
+ for (auto iter = expr.fbegin(), end = expr.fend(); iter != end; ++iter)
+ ++out[*iter];
+ return out;
+ }
+
+ template <class T, class E, class pS>
+ typename std::enable_if<
+ std::tuple_size<pS>::value == 1,
+ types::ndarray<decltype(std::declval<long>() *
+ std::declval<typename E::dtype>()),
+ types::pshape<long>>>::type
+ bincount(types::ndarray<T, pS> const &expr, E const &weights,
+ types::none<long> minlength)
+ {
+ long length = 0;
+ if (minlength)
+ length = (long)minlength;
+ length = std::max<long>(length, 1 + max(expr));
+ typename std::enable_if<
+ std::tuple_size<pS>::value == 1,
+ types::ndarray<decltype(std::declval<long>() *
+ std::declval<typename E::dtype>()),
+ types::pshape<long>>>::type
+ out(types::pshape<long>(length), 0L);
+ auto iweight = weights.begin();
+ for (auto iter = expr.fbegin(), end = expr.fend(); iter != end;
+ ++iter, ++iweight)
+ out[*iter] += *iweight;
+ return out;
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(bincount);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/bitwise_and.hpp b/contrib/python/pythran/pythran/pythonic/numpy/bitwise_and.hpp
new file mode 100644
index 00000000000..51df6420e21
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/bitwise_and.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_NUMPY_BITWISE_AND_HPP
+#define PYTHONIC_NUMPY_BITWISE_AND_HPP
+
+#include "pythonic/include/numpy/bitwise_and.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/operator_/and_.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME bitwise_and
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::and_
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/bitwise_and/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/bitwise_and/accumulate.hpp
new file mode 100644
index 00000000000..556050b398f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/bitwise_and/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_BITWISE_AND_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_BITWISE_AND_ACCUMULATE_HPP
+
+#define UFUNC_NAME bitwise_and
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/bitwise_and/reduce.hpp b/contrib/python/pythran/pythran/pythonic/numpy/bitwise_and/reduce.hpp
new file mode 100644
index 00000000000..e40bf3c2f71
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/bitwise_and/reduce.hpp
@@ -0,0 +1,11 @@
+#ifndef PYTHONIC_NUMPY_BITWISE_AND_REDUCE_HPP
+#define PYTHONIC_NUMPY_BITWISE_AND_REDUCE_HPP
+
+#define UFUNC_NAME bitwise_and
+#define UFUNC_INAME iand
+#include "pythonic/include/numpy/bitwise_and/reduce.hpp"
+#include "pythonic/numpy/ufunc_reduce.hpp"
+#undef UFUNC_NAME
+#undef UFUNC_INAME
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/bitwise_or.hpp b/contrib/python/pythran/pythran/pythonic/numpy/bitwise_or.hpp
new file mode 100644
index 00000000000..17905110c2d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/bitwise_or.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_NUMPY_BITWISE_OR_HPP
+#define PYTHONIC_NUMPY_BITWISE_OR_HPP
+
+#include "pythonic/include/numpy/bitwise_or.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/operator_/or_.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME bitwise_or
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::or_
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/bitwise_or/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/bitwise_or/accumulate.hpp
new file mode 100644
index 00000000000..9e432226cab
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/bitwise_or/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_BITWISE_OR_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_BITWISE_OR_ACCUMULATE_HPP
+
+#define UFUNC_NAME bitwise_or
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/bitwise_or/reduce.hpp b/contrib/python/pythran/pythran/pythonic/numpy/bitwise_or/reduce.hpp
new file mode 100644
index 00000000000..58aec7585fd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/bitwise_or/reduce.hpp
@@ -0,0 +1,11 @@
+#ifndef PYTHONIC_NUMPY_BITWISE_OR_REDUCE_HPP
+#define PYTHONIC_NUMPY_BITWISE_OR_REDUCE_HPP
+
+#define UFUNC_NAME bitwise_or
+#define UFUNC_INAME ior
+#include "pythonic/include/numpy/bitwise_or/reduce.hpp"
+#include "pythonic/numpy/ufunc_reduce.hpp"
+#undef UFUNC_NAME
+#undef UFUNC_INAME
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/bitwise_xor.hpp b/contrib/python/pythran/pythran/pythonic/numpy/bitwise_xor.hpp
new file mode 100644
index 00000000000..ee95e635575
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/bitwise_xor.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_NUMPY_BITWISE_XOR_HPP
+#define PYTHONIC_NUMPY_BITWISE_XOR_HPP
+
+#include "pythonic/include/numpy/bitwise_xor.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/operator_/xor_.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME bitwise_xor
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::xor_
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/bitwise_xor/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/bitwise_xor/accumulate.hpp
new file mode 100644
index 00000000000..f1c1fb67929
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/bitwise_xor/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_BITWISE_XOR_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_BITWISE_XOR_ACCUMULATE_HPP
+
+#define UFUNC_NAME bitwise_xor
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/bitwise_xor/reduce.hpp b/contrib/python/pythran/pythran/pythonic/numpy/bitwise_xor/reduce.hpp
new file mode 100644
index 00000000000..48c3e157319
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/bitwise_xor/reduce.hpp
@@ -0,0 +1,11 @@
+#ifndef PYTHONIC_NUMPY_BITWISE_XOR_REDUCE_HPP
+#define PYTHONIC_NUMPY_BITWISE_XOR_REDUCE_HPP
+
+#define UFUNC_NAME bitwise_xor
+#define UFUNC_INAME ixor
+#include "pythonic/include/numpy/bitwise_xor/reduce.hpp"
+#include "pythonic/numpy/ufunc_reduce.hpp"
+#undef UFUNC_NAME
+#undef UFUNC_INAME
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/broadcast_to.hpp b/contrib/python/pythran/pythran/pythonic/numpy/broadcast_to.hpp
new file mode 100644
index 00000000000..930b1e0e945
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/broadcast_to.hpp
@@ -0,0 +1,35 @@
+#ifndef PYTHONIC_NUMPY_BROADCAST_TO_HPP
+#define PYTHONIC_NUMPY_BROADCAST_TO_HPP
+
+#include "pythonic/include/numpy/broadcast_to.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/numpy/empty.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E, class pS>
+ auto broadcast_to(E const &expr, pS shape)
+ -> decltype(numpy::functor::empty{}(
+ shape, typename types::dtype_t<typename types::dtype_of<E>::type>{}))
+ {
+ using dtype = typename types::dtype_of<E>::type;
+ using BExpr =
+ typename std::conditional<std::is_scalar<E>::value,
+ types::broadcast<E, dtype>, E const &>::type;
+ auto out = numpy::functor::empty{}(shape, typename types::dtype_t<dtype>{});
+ using array_type = decltype(out);
+ BExpr bexpr = expr;
+ utils::broadcast_copy<array_type, E, array_type::value,
+ array_type::value -
+ utils::nested_container_depth<E>::value,
+ std::remove_reference<BExpr>::type::is_vectorizable>(
+ out, bexpr);
+ return out;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/byte.hpp b/contrib/python/pythran/pythran/pythonic/numpy/byte.hpp
new file mode 100644
index 00000000000..6bc80e6f941
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/byte.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_NUMPY_BYTE_HPP
+#define PYTHONIC_NUMPY_BYTE_HPP
+
+#include "pythonic/include/numpy/byte.hpp"
+
+#include "pythonic/types/numpy_op_helper.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/meta.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ inline char byte()
+ {
+ return {};
+ }
+
+ template <class V>
+ char byte(V v)
+ {
+ return v;
+ }
+ } // namespace details
+
+#define NUMPY_NARY_FUNC_NAME byte
+#define NUMPY_NARY_FUNC_SYM details::byte
+#include "pythonic/types/numpy_nary_expr.hpp"
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/cbrt.hpp b/contrib/python/pythran/pythran/pythonic/numpy/cbrt.hpp
new file mode 100644
index 00000000000..c8208e84c1a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/cbrt.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_NUMPY_CBRT_HPP
+#define PYTHONIC_NUMPY_CBRT_HPP
+
+#include "pythonic/include/numpy/cbrt.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME cbrt
+#define NUMPY_NARY_FUNC_SYM xsimd::cbrt
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/clip.hpp b/contrib/python/pythran/pythran/pythonic/numpy/clip.hpp
new file mode 100644
index 00000000000..6a5efe4a979
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/clip.hpp
@@ -0,0 +1,47 @@
+#ifndef PYTHONIC_NUMPY_CLIP_HPP
+#define PYTHONIC_NUMPY_CLIP_HPP
+
+#include "pythonic/include/numpy/clip.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME _clip_max
+#define NUMPY_NARY_FUNC_SYM xsimd::min
+#include "pythonic/types/numpy_nary_expr.hpp"
+
+ namespace wrapper
+ {
+ template <class T, class Mi, class Ma>
+ typename __combined<T, Mi, Ma>::type clip(T const &v, Mi a_min, Ma a_max)
+ {
+ if (v < a_min)
+ return a_min;
+ else if (v > a_max)
+ return a_max;
+ else
+ return v;
+ }
+
+ template <class T, class Mi>
+ typename __combined<T, Mi>::type clip(T const &v, Mi a_min)
+ {
+ if (v < a_min)
+ return a_min;
+ else
+ return v;
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME clip
+#define NUMPY_NARY_FUNC_SYM wrapper::clip
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/complex.hpp b/contrib/python/pythran/pythran/pythonic/numpy/complex.hpp
new file mode 100644
index 00000000000..ce079f3a43b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/complex.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_NUMPY_COMPLEX_HPP
+#define PYTHONIC_NUMPY_COMPLEX_HPP
+
+#include "pythonic/include/numpy/complex.hpp"
+
+#include "pythonic/types/complex.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+ inline std::complex<double> complex(double v, double v2)
+ {
+ return {v, v2};
+ }
+ } // namespace details
+
+#define NUMPY_NARY_FUNC_NAME complex
+#define NUMPY_NARY_FUNC_SYM details::complex
+#include "pythonic/types/numpy_nary_expr.hpp"
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/concatenate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/concatenate.hpp
new file mode 100644
index 00000000000..9efd5cce073
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/concatenate.hpp
@@ -0,0 +1,198 @@
+#ifndef PYTHONIC_NUMPY_CONCATENATE_HPP
+#define PYTHONIC_NUMPY_CONCATENATE_HPP
+
+#include "pythonic/include/numpy/concatenate.hpp"
+
+#include "pythonic/builtins/ValueError.hpp"
+#include "pythonic/builtins/sum.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/allocate.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ template <size_t N>
+ struct concatenate_helper {
+ // list version
+ template <class Out, class A>
+ void operator()(Out &&out, A const &from, long axis) const
+ {
+ if (axis == 0) {
+ auto out_iter = out.begin();
+ for (auto &&ifrom : from)
+ out_iter = std::copy(ifrom.begin(), ifrom.end(), out_iter);
+ } else {
+ using iterator_on_from_value = typename A::value_type::const_iterator;
+ std::vector<iterator_on_from_value,
+ utils::allocator<iterator_on_from_value>>
+ ifroms;
+ for (auto &ifrom : from)
+ ifroms.emplace_back(ifrom.begin());
+
+ using iterator_value_type =
+ typename std::iterator_traits<iterator_on_from_value>::value_type;
+ std::vector<iterator_value_type,
+ utils::allocator<iterator_value_type>>
+ difroms;
+
+ for (auto &&iout : out) {
+ difroms.clear();
+ for (auto &ifrom : ifroms)
+ difroms.emplace_back(*ifrom);
+ concatenate_helper<N - 1>()(iout, difroms, axis - 1);
+ for (auto &ifrom : ifroms)
+ ++ifrom;
+ }
+ }
+ }
+ // array version
+ template <class Out, class A, size_t... I>
+ void operator()(Out &&out, A const &from, long axis,
+ utils::index_sequence<I...>) const
+ {
+ if (axis == 0) {
+ auto out_iter = out.begin();
+ (void)std::initializer_list<int>{
+ (out_iter = std::copy(std::get<I>(from).begin(),
+ std::get<I>(from).end(), out_iter),
+ 1)...};
+ } else {
+ types::array<typename A::value_type::const_iterator, sizeof...(I)>
+ ifroms = {std::get<I>(from).begin()...};
+
+ for (auto &&iout : out) {
+ types::array<
+ typename std::iterator_traits<
+ typename A::value_type::const_iterator>::value_type,
+ sizeof...(I)>
+ difroms = {*std::get<I>(ifroms)...};
+ concatenate_helper<N - 1>()(iout, difroms, axis - 1,
+ utils::index_sequence<I...>{});
+ (void)std::initializer_list<int>{(++std::get<I>(ifroms), 0)...};
+ }
+ }
+ }
+ // tuple version
+ template <class Out, class... Ts, size_t... I>
+ void operator()(Out &&out, std::tuple<Ts...> const &from, long axis,
+ utils::index_sequence<I...>) const
+ {
+ if (axis == 0) {
+ auto out_iter = out.begin();
+ (void)std::initializer_list<int>{
+ (out_iter = std::copy(std::get<I>(from).begin(),
+ std::get<I>(from).end(), out_iter),
+ 1)...};
+ } else {
+ auto ifroms = std::make_tuple(std::get<I>(from).begin()...);
+
+ for (auto &&iout : out) {
+ auto difroms = std::make_tuple(*std::get<I>(ifroms)...);
+ concatenate_helper<N - 1>()(iout, difroms, axis - 1,
+ utils::index_sequence<I...>{});
+ (void)std::initializer_list<int>{(++std::get<I>(ifroms), 0)...};
+ }
+ }
+ }
+ };
+
+ template <>
+ struct concatenate_helper<0> {
+ // list version - sentinel
+ template <class Out, class A>
+ void operator()(Out &&buffer, A const &from, long axis) const
+ {
+ }
+ // array version
+ template <class Out, class E, size_t... I>
+ void operator()(Out &&, E const &, long,
+ utils::index_sequence<I...>) const
+ {
+ }
+ // tuple version - sentinel
+ template <class Out, class... Ts, size_t... I>
+ void operator()(Out &&, std::tuple<Ts...> const &, long,
+ utils::index_sequence<I...>) const
+ {
+ }
+ };
+
+ template <class A, size_t... I>
+ long concatenate_axis_size(A const &from, long axis,
+ utils::index_sequence<I...>)
+ {
+ long sizes[] = {sutils::getshape(std::get<I>(from))[axis]...};
+ return std::accumulate(std::begin(sizes), std::end(sizes), 0L,
+ std::plus<long>());
+ }
+ } // namespace details
+
+ template <class... Types>
+ auto
+ concatenate(std::tuple<Types...> const &args, long axis) -> types::ndarray<
+ typename __combined<typename std::decay<Types>::type::dtype...>::type,
+ types::array<long,
+ std::tuple_element<0, std::tuple<Types...>>::type::value>>
+ {
+ using T =
+ typename __combined<typename std::decay<Types>::type::dtype...>::type;
+ auto constexpr N = std::decay<decltype(std::get<0>(args))>::type::value;
+ auto shape = sutils::getshape(std::get<0>(args));
+ shape[axis] = details::concatenate_axis_size(
+ args, axis, utils::make_index_sequence<sizeof...(Types)>{});
+
+ types::ndarray<
+ typename __combined<typename std::decay<Types>::type::dtype...>::type,
+ types::array<long,
+ std::decay<decltype(std::get<0>(args))>::type::value>>
+ result{shape, types::none_type{}};
+ details::concatenate_helper<N>()(
+ result, args, axis, utils::make_index_sequence<sizeof...(Types)>{});
+ return result;
+ }
+
+ template <class E, size_t M, class V>
+ types::ndarray<typename E::dtype, types::array<long, E::value>>
+ concatenate(types::array_base<E, M, V> const &args, long axis)
+ {
+ using T = typename E::dtype;
+ auto constexpr N = E::value;
+ auto shape = sutils::getshape(std::get<0>(args));
+ shape[axis] = details::concatenate_axis_size(
+ args, axis, utils::make_index_sequence<M>{});
+ types::ndarray<typename E::dtype, types::array<long, E::value>> out(
+ shape, types::none_type{});
+ details::concatenate_helper<N>()(out, args, axis,
+ utils::make_index_sequence<M>{});
+ return out;
+ }
+
+ template <class E>
+ types::ndarray<typename E::dtype, types::array<long, E::value>>
+ concatenate(types::list<E> const &ai, long axis)
+ {
+ using return_type =
+ types::ndarray<typename E::dtype, types::array<long, E::value>>;
+ using T = typename return_type::dtype;
+ auto constexpr N = return_type::value;
+ auto shape = sutils::getshape(ai[0]);
+ shape[axis] = std::accumulate(ai.begin(), ai.end(), 0L,
+ [axis](long v, E const &from) {
+ return v + sutils::getshape(from)[axis];
+ });
+
+ return_type out{shape, types::none_type{}};
+ details::concatenate_helper<N>()(out, ai, axis);
+ return out;
+ ;
+ }
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/convolve.hpp b/contrib/python/pythran/pythran/pythonic/numpy/convolve.hpp
new file mode 100644
index 00000000000..49ef2bd28eb
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/convolve.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_NUMPY_CONVOLVE_HPP
+#define PYTHONIC_NUMPY_CONVOLVE_HPP
+
+#include "pythonic/include/numpy/convolve.hpp"
+#include "pythonic/numpy/correlate.hpp"
+#include "pythonic/numpy/flip.hpp"
+#include "pythonic/numpy/conjugate.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class A, class B, typename U>
+ types::ndarray<typename A::dtype, types::pshape<long>>
+ convolve(A const &inA, B const &inB, U type)
+ {
+ auto inB_flipped = functor::flip{}(inB, 0);
+ auto inB_flip_conj = functor::conjugate{}(inB_flipped);
+ return functor::correlate{}(inA, inB_flip_conj, type);
+ }
+
+ template <class A, class B>
+ types::ndarray<typename A::dtype, types::pshape<long>> convolve(A const &inA,
+ B const &inB)
+ {
+ auto inB_flipped = functor::flip{}(inB, 0);
+ auto inB_flip_conj = functor::conjugate{}(inB_flipped);
+ return functor::correlate{}(inA, inB_flip_conj, "full");
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(convolve)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/copy.hpp b/contrib/python/pythran/pythran/pythonic/numpy/copy.hpp
new file mode 100644
index 00000000000..03660150303
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/copy.hpp
@@ -0,0 +1,58 @@
+#ifndef PYTHONIC_NUMPY_COPY_HPP
+#define PYTHONIC_NUMPY_COPY_HPP
+
+#include "pythonic/include/numpy/copy.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_conversion.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ // list case
+ template <class E>
+ typename std::enable_if<
+ !types::is_array<E>::value && !types::is_dtype<E>::value,
+ types::ndarray<typename E::dtype, types::array<long, E::value>>>::type
+ copy(E const &v)
+ {
+ return {v};
+ }
+
+ // scalar / complex case
+ template <class E>
+ auto copy(E const &v) ->
+ typename std::enable_if<types::is_dtype<E>::value, E>::type
+ {
+ return v;
+ }
+
+ // No copy is required for numpy_expr
+ template <class E>
+ auto copy(E &&v) ->
+ typename std::enable_if<types::is_array<E>::value,
+ decltype(std::forward<E>(v))>::type
+ {
+ return std::forward<E>(v);
+ }
+
+ // ndarray case
+ template <class T, class pS>
+ types::ndarray<T, pS> copy(types::ndarray<T, pS> const &a)
+ {
+ return a.copy();
+ }
+
+ // transposed ndarray case
+ template <class T, class pS>
+ types::numpy_texpr<types::ndarray<T, pS>>
+ copy(types::numpy_texpr<types::ndarray<T, pS>> const &a)
+ {
+ return a.arg.copy();
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/copysign.hpp b/contrib/python/pythran/pythran/pythonic/numpy/copysign.hpp
new file mode 100644
index 00000000000..35c44dafe0f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/copysign.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_NUMPY_COPYSIGN_HPP
+#define PYTHONIC_NUMPY_COPYSIGN_HPP
+
+#include "pythonic/include/numpy/copysign.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME copysign
+#define NUMPY_NARY_FUNC_SYM xsimd::copysign
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/copysign/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/copysign/accumulate.hpp
new file mode 100644
index 00000000000..18df69ef926
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/copysign/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_COPYSIGN_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_COPYSIGN_ACCUMULATE_HPP
+
+#define UFUNC_NAME copysign
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/correlate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/correlate.hpp
new file mode 100644
index 00000000000..f87d8bf2573
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/correlate.hpp
@@ -0,0 +1,120 @@
+#ifndef PYTHONIC_NUMPY_CORRELATE_HPP
+#define PYTHONIC_NUMPY_CORRELATE_HPP
+
+#include "pythonic/include/numpy/correlate.hpp"
+#include "pythonic/numpy/asarray.hpp"
+#include "pythonic/numpy/conjugate.hpp"
+#include "pythonic/numpy/dot.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class A, class B>
+ types::ndarray<typename A::dtype, types::pshape<long>>
+ do_correlate(A const &inA, B const &inB, types::str const &type, int out_inc)
+ // out_inc is used to indicate the inputs were swapped, which means that the
+ // output must be time reversed and conjugated
+ {
+ auto shapeA = sutils::getshape(inA);
+ auto shapeB = sutils::getshape(inB);
+
+ long NA = shapeA[0];
+ long NB = shapeB[0];
+
+ using out_type =
+ typename __combined<typename A::dtype, typename B::dtype>::type;
+ // At this point, handling views would slow things down tremendously
+ auto inA_ = functor::asarray{}(inA);
+ auto inB_ = functor::asarray{}(inB);
+
+ auto outN = 0;
+ int iLeft;
+ if (type == "full") {
+ outN = NA + NB - 1;
+ iLeft = -NB + 1;
+ } else if (type == "valid") {
+ outN = NA - NB + 1;
+ iLeft = 0;
+ } else {
+ assert(type == "same" && "valid type");
+ outN = NA;
+ iLeft = -NB + 1 + (NB - 1) / 2;
+ }
+ // We need outN output values, no matter what.
+ int iRight = iLeft + outN;
+
+ // Allocate output array
+ types::ndarray<out_type, types::pshape<long>> out = {outN, out_type()};
+ out_type *out_ptr = (out_type *)out.buffer;
+ // if out_inc is -1, we reverse the output.
+ if (out_inc == -1)
+ out_ptr += outN - 1;
+
+ // For small correlations, numpy uses small_correlate, far more efficient.
+ // see numpy/core/src/multiarray/arraytypes.c.src
+
+ if (out_inc == 1) {
+ // Incomplete overlap left
+ for (int i = iLeft; i < 0; i++, out_ptr++) {
+ *out_ptr = numpy::dot(inA_(types::fast_contiguous_slice(0, NB + i)),
+ inB_(types::fast_contiguous_slice(-i, NB)));
+ }
+ // Complete overlap middle
+ for (int i = 0; i <= NA - NB; i++, out_ptr++) {
+ *out_ptr = numpy::dot(inA_(types::fast_contiguous_slice(i, i + NB)),
+ inB_(types::fast_contiguous_slice(0, NB)));
+ }
+ // Incomplete overlap right.
+ for (int i = NA - NB + 1; i < iRight; i++, out_ptr++) {
+ *out_ptr = numpy::dot(inA_(types::fast_contiguous_slice(i, NA)),
+ inB_(types::fast_contiguous_slice(0, NA - i)));
+ }
+ } else {
+ // Incomplete overlap left
+ for (int i = iLeft; i < 0; i++, out_ptr += out_inc) {
+ *out_ptr = wrapper::conjugate(
+ numpy::dot(inA_(types::fast_contiguous_slice(0, NB + i)),
+ inB_(types::fast_contiguous_slice(-i, NB))));
+ }
+ // Complete overlap middle
+ for (int i = 0; i <= NA - NB; i++, out_ptr += out_inc) {
+ *out_ptr = wrapper::conjugate(
+ numpy::dot(inA_(types::fast_contiguous_slice(i, i + NB)),
+ inB_(types::fast_contiguous_slice(0, NB))));
+ }
+ // Incomplete overlap right.
+ for (int i = NA - NB + 1; i < iRight; i++, out_ptr += out_inc) {
+ *out_ptr = wrapper::conjugate(
+ numpy::dot(inA_(types::fast_contiguous_slice(i, NA)),
+ inB_(types::fast_contiguous_slice(0, NA - i))));
+ }
+ }
+
+ return out;
+ }
+
+ template <class A, class B>
+ types::ndarray<typename A::dtype, types::pshape<long>>
+ correlate(A const &inA, B const &inB, types::str const &type)
+ {
+ long NA = inA.template shape<0>();
+ long NB = inB.template shape<0>();
+ // If inB is longer than inA, swap them, but time-reverse and conjugate the
+ // output (-1 flag)
+ if (NA > NB) {
+ auto inB_conj = functor::conjugate{}(inB);
+ return do_correlate(inA, inB_conj, type, 1);
+ } else {
+ auto inA_conj = functor::conjugate{}(inA);
+ return do_correlate(inB, inA_conj, type, -1);
+ }
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(correlate)
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/cosh.hpp b/contrib/python/pythran/pythran/pythonic/numpy/cosh.hpp
new file mode 100644
index 00000000000..92354b55606
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/cosh.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_NUMPY_COSH_HPP
+#define PYTHONIC_NUMPY_COSH_HPP
+
+#include "pythonic/include/numpy/cosh.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+#include <xsimd/xsimd.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME cosh
+#define NUMPY_NARY_FUNC_SYM xsimd::cosh
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/count_nonzero.hpp b/contrib/python/pythran/pythran/pythonic/numpy/count_nonzero.hpp
new file mode 100644
index 00000000000..95d92948998
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/count_nonzero.hpp
@@ -0,0 +1,51 @@
+#ifndef PYTHONIC_NUMPY_COUNT_NONZERO_HPP
+#define PYTHONIC_NUMPY_COUNT_NONZERO_HPP
+
+#include "pythonic/include/numpy/count_nonzero.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class dtype, class E>
+ auto _count_nonzero(E begin, E end, long &count, utils::int_<1>) ->
+ typename std::enable_if<std::is_same<dtype, bool>::value>::type
+ {
+ for (; begin != end; ++begin)
+ // Behaviour defined in the standard
+ count += *begin;
+ }
+
+ template <class dtype, class E>
+ auto _count_nonzero(E begin, E end, long &count, utils::int_<1>) ->
+ typename std::enable_if<!std::is_same<dtype, bool>::value>::type
+ {
+ for (; begin != end; ++begin)
+ if (*begin != static_cast<dtype>(0))
+ ++count;
+ }
+
+ template <class dtype, class E, size_t N>
+ void _count_nonzero(E begin, E end, long &count, utils::int_<N>)
+ {
+ for (; begin != end; ++begin)
+ _count_nonzero<dtype>((*begin).begin(), (*begin).end(), count,
+ utils::int_<N - 1>());
+ }
+
+ template <class E>
+ long count_nonzero(E const &array)
+ {
+ long count(0);
+ _count_nonzero<typename E::dtype>(array.begin(), array.end(), count,
+ utils::int_<E::value>());
+ return count;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/cross.hpp b/contrib/python/pythran/pythran/pythonic/numpy/cross.hpp
new file mode 100644
index 00000000000..574a87ff02d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/cross.hpp
@@ -0,0 +1,148 @@
+#ifndef PYTHONIC_NUMPY_CROSS_HPP
+#define PYTHONIC_NUMPY_CROSS_HPP
+
+#include "pythonic/include/numpy/cross.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <size_t N, size_t En, size_t Fn>
+ struct _cross {
+ template <class Out, class E, class F>
+ void operator()(Out obegin, Out oend, E ebegin, F fbegin)
+ {
+ while (obegin != oend) {
+ _cross<N - 1, En, Fn>{}((*obegin).begin(), (*obegin).end(),
+ (*ebegin).begin(), (*fbegin).begin());
+ ++obegin, ++ebegin, ++fbegin;
+ }
+ }
+ };
+ template <>
+ struct _cross<1, 2, 2> {
+ template <class Out, class E, class F>
+ void operator()(Out obegin, Out oend, E ebegin, F fbegin)
+ {
+ auto e0 = *ebegin;
+ ++ebegin;
+ auto e1 = *ebegin;
+ auto f0 = *fbegin;
+ ++fbegin;
+ auto f1 = *fbegin;
+ *obegin = e0 *f1 - e1 *f0;
+ }
+ };
+ template <>
+ struct _cross<1, 2, 3> {
+ template <class Out, class E, class F>
+ void operator()(Out obegin, Out oend, E ebegin, F fbegin)
+ {
+ auto e0 = *ebegin;
+ ++ebegin;
+ auto e1 = *ebegin;
+ decltype(e1) e2 = 0;
+ auto f0 = *fbegin;
+ ++fbegin;
+ auto f1 = *fbegin;
+ ++fbegin;
+ auto f2 = *fbegin;
+ *obegin = e1 *f2 - e2 *f1;
+ ++obegin;
+ *obegin = e2 *f0 - e0 *f2;
+ ++obegin;
+ *obegin = e0 *f1 - e1 *f0;
+ }
+ };
+ template <>
+ struct _cross<1, 3, 3> {
+ template <class Out, class E, class F>
+ void operator()(Out obegin, Out oend, E ebegin, F fbegin)
+ {
+ auto e0 = *ebegin;
+ ++ebegin;
+ auto e1 = *ebegin;
+ ++ebegin;
+ auto e2 = *ebegin;
+ auto f0 = *fbegin;
+ ++fbegin;
+ auto f1 = *fbegin;
+ ++fbegin;
+ auto f2 = *fbegin;
+ *obegin = e1 *f2 - e2 *f1;
+ ++obegin;
+ *obegin = e2 *f0 - e0 *f2;
+ ++obegin;
+ *obegin = e0 *f1 - e1 *f0;
+ }
+ };
+ template <>
+ struct _cross<1, 3, 2> {
+ template <class Out, class E, class F>
+ void operator()(Out obegin, Out oend, E ebegin, F fbegin)
+ {
+ auto e0 = *ebegin;
+ ++ebegin;
+ auto e1 = *ebegin;
+ ++ebegin;
+ auto e2 = *ebegin;
+ auto f0 = *fbegin;
+ ++fbegin;
+ auto f1 = *fbegin;
+ decltype(f1) f2 = 0;
+ *obegin = e1 *f2 - e2 *f1;
+ ++obegin;
+ *obegin = e2 *f0 - e0 *f2;
+ ++obegin;
+ *obegin = e0 *f1 - e1 *f0;
+ }
+ };
+
+ template <class E, class F>
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::array<long, E::value>>
+ cross(E const &e, F const &f)
+ {
+ using dtype =
+ typename __combined<typename E::dtype, typename F::dtype>::type;
+ types::array<long, E::value> out_shape;
+ sutils::copy_shape<0, 0>(out_shape, e,
+ utils::make_index_sequence<E::value - 1>());
+ if (e.template shape<E::value - 1>() == 2) {
+ if (f.template shape<F::value - 1>() == 2) {
+ out_shape[E::value - 1] = 1;
+ types::ndarray<dtype, types::array<long, E::value>> out{
+ out_shape, types::none_type{}};
+ _cross<E::value, 2, 2>{}(out.begin(), out.end(), e.begin(), f.begin());
+ return out;
+ } else {
+ out_shape[E::value - 1] = 3;
+ types::ndarray<dtype, types::array<long, E::value>> out{
+ out_shape, types::none_type{}};
+ _cross<E::value, 2, 3>{}(out.begin(), out.end(), e.begin(), f.begin());
+ return out;
+ }
+ } else {
+ if (f.template shape<F::value - 1>() == 2) {
+ out_shape[E::value - 1] = 3;
+ types::ndarray<dtype, types::array<long, E::value>> out{
+ out_shape, types::none_type{}};
+ _cross<E::value, 3, 2>{}(out.begin(), out.end(), e.begin(), f.begin());
+ return out;
+ } else {
+ out_shape[E::value - 1] = 3;
+ types::ndarray<dtype, types::array<long, E::value>> out{
+ out_shape, types::none_type{}};
+ _cross<E::value, 3, 3>{}(out.begin(), out.end(), e.begin(), f.begin());
+ return out;
+ }
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ctypeslib/as_array.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ctypeslib/as_array.hpp
new file mode 100644
index 00000000000..5566ddc85b4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ctypeslib/as_array.hpp
@@ -0,0 +1,32 @@
+#ifndef PYTHONIC_NUMPY_CTYPESLIB_AS_ARRAY_HPP
+#define PYTHONIC_NUMPY_CTYPESLIB_AS_ARRAY_HPP
+
+#include "pythonic/include/numpy/ctypeslib/as_array.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/pointer.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace ctypeslib
+ {
+ template <class T, class pS>
+ typename std::enable_if<!std::is_integral<pS>::value,
+ types::ndarray<T, pS>>::type
+ as_array(types::pointer<T> ptr, pS shape)
+ {
+ return {ptr.data, shape, types::ownership::external};
+ }
+
+ template <class T>
+ types::ndarray<T, types::pshape<long>> as_array(types::pointer<T> ptr,
+ long size)
+ {
+ return as_array(ptr, types::pshape<long>{size});
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/cumprod.hpp b/contrib/python/pythran/pythran/pythonic/numpy/cumprod.hpp
new file mode 100644
index 00000000000..d8685e40967
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/cumprod.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_NUMPY_CUMPROD_HPP
+#define PYTHONIC_NUMPY_CUMPROD_HPP
+
+#include "pythonic/include/numpy/cumprod.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/numpy/partial_sum.hpp"
+#include "pythonic/operator_/imul.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class E, class... Opts>
+ auto cumprod(E &&e, Opts &&... opts)
+ -> decltype(partial_sum<operator_::functor::imul>(
+ std::forward<E>(e), std::forward<Opts>(opts)...))
+ {
+ return partial_sum<operator_::functor::imul>(std::forward<E>(e),
+ std::forward<Opts>(opts)...);
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(cumprod);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/cumproduct.hpp b/contrib/python/pythran/pythran/pythonic/numpy/cumproduct.hpp
new file mode 100644
index 00000000000..5f0468310a6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/cumproduct.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_CUMPRODUCT_HPP
+#define PYTHONIC_NUMPY_CUMPRODUCT_HPP
+
+#include "pythonic/include/numpy/cumproduct.hpp"
+#include "pythonic/numpy/cumprod.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/cumsum.hpp b/contrib/python/pythran/pythran/pythonic/numpy/cumsum.hpp
new file mode 100644
index 00000000000..2415ff3c11c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/cumsum.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_NUMPY_CUMSUM_HPP
+#define PYTHONIC_NUMPY_CUMSUM_HPP
+
+#include "pythonic/include/numpy/cumsum.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/numpy/partial_sum.hpp"
+#include "pythonic/operator_/iadd.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class E, class... Opts>
+ auto cumsum(E &&e, Opts &&... opts)
+ -> decltype(partial_sum<operator_::functor::add>(
+ std::forward<E>(e), std::forward<Opts>(opts)...))
+ {
+ return partial_sum<operator_::functor::add>(std::forward<E>(e),
+ std::forward<Opts>(opts)...);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/deg2rad.hpp b/contrib/python/pythran/pythran/pythonic/numpy/deg2rad.hpp
new file mode 100644
index 00000000000..6fb4e5a9823
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/deg2rad.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_NUMPY_DEG2RAD_HPP
+#define PYTHONIC_NUMPY_DEG2RAD_HPP
+
+#include "pythonic/include/numpy/deg2rad.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/numpy/pi.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME deg2rad
+#define NUMPY_NARY_FUNC_SYM wrapper::deg2rad
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/degrees.hpp b/contrib/python/pythran/pythran/pythonic/numpy/degrees.hpp
new file mode 100644
index 00000000000..3d9cab33318
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/degrees.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_DEGREES_HPP
+#define PYTHONIC_NUMPY_DEGREES_HPP
+
+#include "pythonic/include/numpy/degrees.hpp"
+#include "pythonic/numpy/rad2deg.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/delete_.hpp b/contrib/python/pythran/pythran/pythonic/numpy/delete_.hpp
new file mode 100644
index 00000000000..b5ac3415c08
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/delete_.hpp
@@ -0,0 +1,49 @@
+#ifndef PYTHONIC_NUMPY_DELETE_HPP
+#define PYTHONIC_NUMPY_DELETE_HPP
+
+#include "pythonic/include/numpy/delete_.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS>
+ types::ndarray<T, types::pshape<long>>
+ delete_(types::ndarray<T, pS> const &a, long index, types::none_type axis)
+ {
+ types::ndarray<T, types::pshape<long>> out(
+ types::pshape<long>(long(a.flat_size()) - 1), builtins::None);
+ long n = a.flat_size();
+ index = std::min(n, index);
+ std::copy(a.buffer + index + 1, a.buffer + n,
+ std::copy(a.buffer, a.buffer + index, out.buffer));
+ return out;
+ }
+
+ template <class T, class pS, class I>
+ typename std::enable_if<!std::is_scalar<I>::value,
+ types::ndarray<T, types::pshape<long>>>::type
+ delete_(types::ndarray<T, pS> const &in, I const &indices,
+ types::none_type axis)
+ {
+ types::ndarray<T, types::pshape<long>> out(
+ types::pshape<long>(long(in.flat_size()) - indices.flat_size()),
+ builtins::None);
+ auto out_iter = out.buffer;
+ auto in_iter = in.buffer;
+ for (long index : indices) {
+ out_iter = std::copy(in_iter, in.buffer + index, out_iter);
+ in_iter = in.buffer + index + 1;
+ }
+ std::copy(in_iter, in.buffer + in.flat_size(), out_iter);
+ return out;
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(delete_);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/diag.hpp b/contrib/python/pythran/pythran/pythonic/numpy/diag.hpp
new file mode 100644
index 00000000000..a5e12357b7a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/diag.hpp
@@ -0,0 +1,64 @@
+#ifndef PYTHONIC_NUMPY_DIAG_HPP
+#define PYTHONIC_NUMPY_DIAG_HPP
+
+#include "pythonic/include/numpy/diag.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_conversion.hpp"
+#include "pythonic/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS>
+ typename std::enable_if<std::tuple_size<pS>::value == 2,
+ types::ndarray<T, types::pshape<long>>>::type
+ diag(types::ndarray<T, pS> const &a, long k)
+ {
+ auto &&a_shape = a._shape;
+ utils::shared_ref<types::raw_array<T>> buffer(
+ std::max(std::get<0>(a_shape), std::get<1>(a_shape)));
+ types::pshape<long> shape = 0;
+ auto iter = buffer->data;
+ if (k >= 0)
+ for (int i = 0, j = k;
+ i < std::get<0>(a_shape) && j < std::get<1>(a_shape);
+ ++i, ++j, ++std::get<0>(shape))
+ *iter++ = a[i][j];
+ else
+ for (int i = -k, j = 0;
+ i < std::get<0>(a_shape) && j < std::get<1>(a_shape);
+ ++i, ++j, ++std::get<0>(shape))
+ *iter++ = a[i][j];
+ return {buffer, shape};
+ }
+
+ template <class T, class pS>
+ typename std::enable_if<std::tuple_size<pS>::value == 1,
+ types::ndarray<T, types::array<long, 2>>>::type
+ diag(types::ndarray<T, pS> const &a, long k)
+ {
+ long n = a.flat_size() + std::abs(k);
+ types::ndarray<T, types::array<long, 2>> out(types::make_tuple(n, n), 0);
+ if (k >= 0)
+ for (long i = 0, j = k; i < n && j < n; ++i, ++j)
+ out[i][j] = a[i];
+ else
+ for (long i = -k, j = 0; i < n && j < n; ++i, ++j)
+ out[i][j] = a[j];
+ return out;
+ }
+
+ template <class T>
+ auto diag(types::list<T> const &a, long k) -> decltype(diag(asarray(a), k))
+ {
+ return diag(asarray(a), k);
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(diag);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/diagflat.hpp b/contrib/python/pythran/pythran/pythonic/numpy/diagflat.hpp
new file mode 100644
index 00000000000..ff426c66aa4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/diagflat.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_DIAGFLAT_HPP
+#define PYTHONIC_NUMPY_DIAGFLAT_HPP
+
+#include "pythonic/include/numpy/diagflat.hpp"
+#include "pythonic/numpy/diag.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/diagonal.hpp b/contrib/python/pythran/pythran/pythonic/numpy/diagonal.hpp
new file mode 100644
index 00000000000..e5c1b642036
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/diagonal.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_DIAGONAL_HPP
+#define PYTHONIC_NUMPY_DIAGONAL_HPP
+
+#include "pythonic/include/numpy/diagonal.hpp"
+#include "pythonic/numpy/diag.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/diff.hpp b/contrib/python/pythran/pythran/pythonic/numpy/diff.hpp
new file mode 100644
index 00000000000..5863201ad1c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/diff.hpp
@@ -0,0 +1,66 @@
+#ifndef PYTHONIC_NUMPY_DIFF_HPP
+#define PYTHONIC_NUMPY_DIFF_HPP
+
+#include "pythonic/include/numpy/diff.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace details
+ {
+ template <class E>
+ types::ndarray<typename E::dtype, types::array<long, E::value>>
+ diff(E const &arr, long n, long axis)
+ {
+ auto shape = sutils::getshape(arr);
+ auto stride = (axis == E::value - 1)
+ ? arr.template shape<E::value - 1>()
+ : std::accumulate(shape.begin() + axis + 1, shape.end(),
+ 1L, std::multiplies<long>());
+ --shape[axis];
+
+ // this does not leak, but uses slightly too much memory
+ auto out = arr.reshape(shape);
+
+ auto iter = arr.fbegin();
+ auto out_iter = out.fbegin();
+
+ if (axis == E::value - 1) {
+ for (long i = 0, sz = arr.flat_size(); i < sz; i += stride) {
+ auto prev = *(iter + i);
+ for (long k = 1; k < stride; ++k, ++out_iter) {
+ auto nprev = *(iter + i + k);
+ *(out_iter) = nprev - prev;
+ prev = nprev;
+ }
+ }
+ } else {
+ iter += stride;
+ for (auto out_end = out.fend(); out_iter != out_end; ++out_iter) {
+ *out_iter = *iter++ - *out_iter;
+ }
+ }
+ if (n == 1)
+ return out;
+ else
+ return diff(out, n - 1, axis);
+ }
+ }
+ template <class E>
+ types::ndarray<typename E::dtype, types::array<long, E::value>>
+ diff(E const &expr, long n, long axis)
+ {
+ if (axis < 0)
+ axis += E::value;
+ // that's the only allocation that should happen
+ return details::diff(array(expr), n, axis);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/digitize.hpp b/contrib/python/pythran/pythran/pythonic/numpy/digitize.hpp
new file mode 100644
index 00000000000..e5e374f1968
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/digitize.hpp
@@ -0,0 +1,56 @@
+#ifndef PYTHONIC_NUMPY_DIGITIZE_HPP
+#define PYTHONIC_NUMPY_DIGITIZE_HPP
+
+#include "pythonic/include/numpy/digitize.hpp"
+
+#include "pythonic/numpy/asarray.hpp"
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/operator_/gt.hpp"
+#include "pythonic/operator_/lt.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace
+ {
+ template <class I, class O, class B, class Op>
+ void _digitize(I begin, I end, O &out, B &bins, Op const &op,
+ utils::int_<1>)
+ {
+ for (; begin != end; ++begin, ++out)
+ *out = std::lower_bound(bins.begin(), bins.end(), *begin, op) -
+ bins.begin();
+ }
+
+ template <class I, class O, class B, class Op, size_t N>
+ void _digitize(I begin, I end, O &out, B &bins, Op const &op,
+ utils::int_<N>)
+ {
+ for (; begin != end; ++begin)
+ _digitize((*begin).begin(), (*begin).end(), out, bins, op,
+ utils::int_<N - 1>());
+ }
+ }
+
+ template <class E, class F>
+ types::ndarray<long, types::pshape<long>> digitize(E const &expr, F const &b)
+ {
+ auto bins = asarray(b);
+ bool is_increasing =
+ bins.flat_size() > 1 && *bins.fbegin() < *(bins.fbegin() + 1);
+ types::ndarray<long, types::pshape<long>> out(
+ types::make_tuple(long(expr.flat_size())), builtins::None);
+ auto out_iter = out.fbegin();
+ if (is_increasing)
+ _digitize(expr.begin(), expr.end(), out_iter, bins,
+ operator_::functor::lt(), utils::int_<E::value>());
+ else
+ _digitize(expr.begin(), expr.end(), out_iter, bins,
+ operator_::functor::gt(), utils::int_<E::value>());
+ return out;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/divide.hpp b/contrib/python/pythran/pythran/pythonic/numpy/divide.hpp
new file mode 100644
index 00000000000..2be148fb071
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/divide.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_NUMPY_DIVIDE_HPP
+#define PYTHONIC_NUMPY_DIVIDE_HPP
+
+#include "pythonic/include/numpy/divide.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/operator_/div.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME divide
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::div
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/divide/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/divide/accumulate.hpp
new file mode 100644
index 00000000000..e219bf6b58f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/divide/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_DIVIDE_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_DIVIDE_ACCUMULATE_HPP
+
+#define UFUNC_NAME divide
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/dot.hpp b/contrib/python/pythran/pythran/pythonic/numpy/dot.hpp
new file mode 100644
index 00000000000..46d93dae997
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/dot.hpp
@@ -0,0 +1,604 @@
+#ifndef PYTHONIC_NUMPY_DOT_HPP
+#define PYTHONIC_NUMPY_DOT_HPP
+
+#include "pythonic/include/numpy/dot.hpp"
+
+#include "pythonic/numpy/multiply.hpp"
+#include "pythonic/numpy/sum.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/traits.hpp"
+
+#ifdef PYTHRAN_BLAS_NONE
+#error pythran configured without BLAS but BLAS seem needed
+#endif
+
+#if defined(PYTHRAN_BLAS_ATLAS) || defined(PYTHRAN_BLAS_SATLAS)
+extern "C" {
+#endif
+#include <cblas.h>
+#if defined(PYTHRAN_BLAS_ATLAS) || defined(PYTHRAN_BLAS_SATLAS)
+}
+#endif
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E, class F>
+ typename std::enable_if<types::is_dtype<E>::value &&
+ types::is_dtype<F>::value,
+ decltype(std::declval<E>() * std::declval<F>())>::type
+ dot(E const &e, F const &f)
+ {
+ return e * f;
+ }
+
+ template <class E>
+ struct blas_buffer_t {
+ typename E::dtype const *operator()(E const &e) const
+ {
+ return e.buffer;
+ }
+ };
+ template <class T>
+ struct blas_buffer_t<types::list<T>> {
+ T const *operator()(types::list<T> const &e) const
+ {
+ return &e.fast(0);
+ }
+ };
+ template <class T, size_t N>
+ struct blas_buffer_t<types::array<T, N>> {
+ T const *operator()(types::array<T, N> const &e) const
+ {
+ return e.data();
+ }
+ };
+
+ template <class E>
+ auto blas_buffer(E const &e) -> decltype(blas_buffer_t<E>{}(e))
+ {
+ return blas_buffer_t<E>{}(e);
+ }
+
+ template <class E, class F>
+ typename std::enable_if<
+ types::is_numexpr_arg<E>::value &&
+ types::is_numexpr_arg<F>::value // Arguments are array_like
+ && E::value == 1 && F::value == 1 // It is a two vectors.
+ && (!is_blas_array<E>::value || !is_blas_array<F>::value ||
+ !std::is_same<typename E::dtype, typename F::dtype>::value),
+ typename __combined<typename E::dtype, typename F::dtype>::type>::type
+ dot(E const &e, F const &f)
+ {
+ return sum(functor::multiply{}(e, f));
+ }
+
+ template <class E, class F>
+ typename std::enable_if<E::value == 1 && F::value == 1 &&
+ std::is_same<typename E::dtype, float>::value &&
+ std::is_same<typename F::dtype, float>::value &&
+ is_blas_array<E>::value &&
+ is_blas_array<F>::value,
+ float>::type
+ dot(E const &e, F const &f)
+ {
+ return cblas_sdot(e.size(), blas_buffer(e), 1, blas_buffer(f), 1);
+ }
+
+ template <class E, class F>
+ typename std::enable_if<E::value == 1 && F::value == 1 &&
+ std::is_same<typename E::dtype, double>::value &&
+ std::is_same<typename F::dtype, double>::value &&
+ is_blas_array<E>::value &&
+ is_blas_array<F>::value,
+ double>::type
+ dot(E const &e, F const &f)
+ {
+ return cblas_ddot(e.size(), blas_buffer(e), 1, blas_buffer(f), 1);
+ }
+
+ template <class E, class F>
+ typename std::enable_if<
+ E::value == 1 && F::value == 1 &&
+ std::is_same<typename E::dtype, std::complex<float>>::value &&
+ std::is_same<typename F::dtype, std::complex<float>>::value &&
+ is_blas_array<E>::value && is_blas_array<F>::value,
+ std::complex<float>>::type
+ dot(E const &e, F const &f)
+ {
+ std::complex<float> out;
+ cblas_cdotu_sub(e.size(), blas_buffer(e), 1, blas_buffer(f), 1, &out);
+ return out;
+ }
+
+ template <class E, class F>
+ typename std::enable_if<
+ E::value == 1 && F::value == 1 &&
+ std::is_same<typename E::dtype, std::complex<double>>::value &&
+ std::is_same<typename F::dtype, std::complex<double>>::value &&
+ is_blas_array<E>::value && is_blas_array<F>::value,
+ std::complex<double>>::type
+ dot(E const &e, F const &f)
+ {
+ std::complex<double> out;
+ cblas_zdotu_sub(e.size(), blas_buffer(e), 1, blas_buffer(f), 1, &out);
+ return out;
+ }
+
+ /// Matrice / Vector multiplication
+
+#define MV_DEF(T, L) \
+ inline void mv(int m, int n, T *A, T *B, T *C) \
+ { \
+ cblas_##L##gemv(CblasRowMajor, CblasNoTrans, n, m, 1, A, m, B, 1, 0, C, \
+ 1); \
+ }
+
+ MV_DEF(double, d)
+ MV_DEF(float, s)
+
+#undef MV_DEF
+
+#define TV_DEF(T, L) \
+ inline void tv(int m, int n, T *A, T *B, T *C) \
+ { \
+ cblas_##L##gemv(CblasRowMajor, CblasTrans, m, n, 1, A, n, B, 1, 0, C, 1); \
+ }
+
+ TV_DEF(double, d)
+ TV_DEF(float, s)
+
+#undef TV_DEF
+
+#define MV_DEF(T, K, L) \
+ inline void mv(int m, int n, T *A, T *B, T *C) \
+ { \
+ T alpha = 1, beta = 0; \
+ cblas_##L##gemv(CblasRowMajor, CblasNoTrans, n, m, (K *)&alpha, (K *)A, m, \
+ (K *)B, 1, (K *)&beta, (K *)C, 1); \
+ }
+ MV_DEF(std::complex<float>, float, c)
+ MV_DEF(std::complex<double>, double, z)
+#undef MV_DEF
+
+ template <class E, class pS0, class pS1>
+ typename std::enable_if<is_blas_type<E>::value &&
+ std::tuple_size<pS0>::value == 2 &&
+ std::tuple_size<pS1>::value == 1,
+ types::ndarray<E, types::pshape<long>>>::type
+ dot(types::ndarray<E, pS0> const &f, types::ndarray<E, pS1> const &e)
+ {
+ types::ndarray<E, types::pshape<long>> out(
+ types::pshape<long>{f.template shape<0>()}, builtins::None);
+ const int m = f.template shape<1>(), n = f.template shape<0>();
+ mv(m, n, f.buffer, e.buffer, out.buffer);
+ return out;
+ }
+
+ template <class E, class pS0, class pS1>
+ typename std::enable_if<is_blas_type<E>::value &&
+ std::tuple_size<pS0>::value == 2 &&
+ std::tuple_size<pS1>::value == 1,
+ types::ndarray<E, types::pshape<long>>>::type
+ dot(types::numpy_texpr<types::ndarray<E, pS0>> const &f,
+ types::ndarray<E, pS1> const &e)
+ {
+ types::ndarray<E, types::pshape<long>> out(
+ types::pshape<long>{f.template shape<0>()}, builtins::None);
+ const int m = f.template shape<1>(), n = f.template shape<0>();
+ tv(m, n, f.arg.buffer, e.buffer, out.buffer);
+ return out;
+ }
+
+// The trick is to not transpose the matrix so that MV become VM
+#define VM_DEF(T, L) \
+ inline void vm(int m, int n, T *A, T *B, T *C) \
+ { \
+ cblas_##L##gemv(CblasRowMajor, CblasTrans, n, m, 1, A, m, B, 1, 0, C, 1); \
+ }
+
+ VM_DEF(double, d)
+ VM_DEF(float, s)
+
+#undef VM_DEF
+#define VT_DEF(T, L) \
+ inline void vt(int m, int n, T *A, T *B, T *C) \
+ { \
+ cblas_##L##gemv(CblasRowMajor, CblasNoTrans, m, n, 1, A, n, B, 1, 0, C, \
+ 1); \
+ }
+
+ VT_DEF(double, d)
+ VT_DEF(float, s)
+
+#undef VM_DEF
+#define VM_DEF(T, K, L) \
+ inline void vm(int m, int n, T *A, T *B, T *C) \
+ { \
+ T alpha = 1, beta = 0; \
+ cblas_##L##gemv(CblasRowMajor, CblasTrans, n, m, (K *)&alpha, (K *)A, m, \
+ (K *)B, 1, (K *)&beta, (K *)C, 1); \
+ }
+ VM_DEF(std::complex<float>, float, c)
+ VM_DEF(std::complex<double>, double, z)
+#undef VM_DEF
+
+ template <class E, class pS0, class pS1>
+ typename std::enable_if<is_blas_type<E>::value &&
+ std::tuple_size<pS0>::value == 1 &&
+ std::tuple_size<pS1>::value == 2,
+ types::ndarray<E, types::pshape<long>>>::type
+ dot(types::ndarray<E, pS0> const &e, types::ndarray<E, pS1> const &f)
+ {
+ types::ndarray<E, types::pshape<long>> out(
+ types::pshape<long>{f.template shape<1>()}, builtins::None);
+ const int m = f.template shape<1>(), n = f.template shape<0>();
+ vm(m, n, f.buffer, e.buffer, out.buffer);
+ return out;
+ }
+
+ template <class E, class pS0, class pS1>
+ typename std::enable_if<is_blas_type<E>::value &&
+ std::tuple_size<pS0>::value == 1 &&
+ std::tuple_size<pS1>::value == 2,
+ types::ndarray<E, types::pshape<long>>>::type
+ dot(types::ndarray<E, pS0> const &e,
+ types::numpy_texpr<types::ndarray<E, pS1>> const &f)
+ {
+ types::ndarray<E, types::pshape<long>> out(
+ types::pshape<long>{f.template shape<1>()}, builtins::None);
+ const int m = f.template shape<1>(), n = f.template shape<0>();
+ vt(m, n, f.arg.buffer, e.buffer, out.buffer);
+ return out;
+ }
+
+ // If arguments could be use with blas, we evaluate them as we need pointer
+ // on array for blas
+ template <class E, class F>
+ typename std::enable_if<
+ types::is_numexpr_arg<E>::value &&
+ types::is_numexpr_arg<F>::value // It is an array_like
+ && (!(types::is_ndarray<E>::value && types::is_ndarray<F>::value) ||
+ !std::is_same<typename E::dtype, typename F::dtype>::value) &&
+ is_blas_type<typename E::dtype>::value &&
+ is_blas_type<typename F::dtype>::value // With dtype compatible with
+ // blas
+ && E::value == 2 && F::value == 1, // And it is matrix / vect
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::pshape<long>>>::type
+ dot(E const &e, F const &f)
+ {
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ typename E::shape_t>
+ e_ = e;
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ typename F::shape_t>
+ f_ = f;
+ return dot(e_, f_);
+ }
+
+ // If arguments could be use with blas, we evaluate them as we need pointer
+ // on array for blas
+ template <class E, class F>
+ typename std::enable_if<
+ types::is_numexpr_arg<E>::value &&
+ types::is_numexpr_arg<F>::value // It is an array_like
+ && (!(types::is_ndarray<E>::value && types::is_ndarray<F>::value) ||
+ !std::is_same<typename E::dtype, typename F::dtype>::value) &&
+ is_blas_type<typename E::dtype>::value &&
+ is_blas_type<typename F::dtype>::value // With dtype compatible with
+ // blas
+ && E::value == 1 && F::value == 2, // And it is vect / matrix
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::pshape<long>>>::type
+ dot(E const &e, F const &f)
+ {
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ typename E::shape_t>
+ e_ = e;
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ typename F::shape_t>
+ f_ = f;
+ return dot(e_, f_);
+ }
+
+ // If one of the arg doesn't have a "blas compatible type", we use a slow
+ // matrix vector multiplication.
+ template <class E, class F>
+ typename std::enable_if<
+ (!is_blas_type<typename E::dtype>::value ||
+ !is_blas_type<typename F::dtype>::value) &&
+ E::value == 1 && F::value == 2, // And it is vect / matrix
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::pshape<long>>>::type
+ dot(E const &e, F const &f)
+ {
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::pshape<long>>
+ out(types::pshape<long>{f.template shape<1>()}, 0);
+ for (long i = 0; i < out.template shape<0>(); i++)
+ for (long j = 0; j < f.template shape<0>(); j++)
+ out[i] += e[j] * f[types::array<long, 2>{{j, i}}];
+ return out;
+ }
+
+ // If one of the arg doesn't have a "blas compatible type", we use a slow
+ // matrix vector multiplication.
+ template <class E, class F>
+ typename std::enable_if<
+ (!is_blas_type<typename E::dtype>::value ||
+ !is_blas_type<typename F::dtype>::value) &&
+ E::value == 2 && F::value == 1, // And it is vect / matrix
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::pshape<long>>>::type
+ dot(E const &e, F const &f)
+ {
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::pshape<long>>
+ out(types::pshape<long>{e.template shape<0>()}, 0);
+ for (long i = 0; i < out.template shape<0>(); i++)
+ for (long j = 0; j < f.template shape<0>(); j++)
+ out[i] += e[types::array<long, 2>{{i, j}}] * f[j];
+ return out;
+ }
+
+ /// Matrix / Matrix multiplication
+
+#define MM_DEF(T, L) \
+ inline void mm(int m, int n, int k, T *A, T *B, T *C) \
+ { \
+ cblas_##L##gemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, m, n, k, 1, A, \
+ k, B, n, 0, C, n); \
+ }
+ MM_DEF(double, d)
+ MM_DEF(float, s)
+#undef MM_DEF
+#define MM_DEF(T, K, L) \
+ inline void mm(int m, int n, int k, T *A, T *B, T *C) \
+ { \
+ T alpha = 1, beta = 0; \
+ cblas_##L##gemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, m, n, k, \
+ (K *)&alpha, (K *)A, k, (K *)B, n, (K *)&beta, (K *)C, n); \
+ }
+ MM_DEF(std::complex<float>, float, c)
+ MM_DEF(std::complex<double>, double, z)
+#undef MM_DEF
+
+ template <class E, class pS0, class pS1>
+ typename std::enable_if<is_blas_type<E>::value &&
+ std::tuple_size<pS0>::value == 2 &&
+ std::tuple_size<pS1>::value == 2,
+ types::ndarray<E, types::array<long, 2>>>::type
+ dot(types::ndarray<E, pS0> const &a, types::ndarray<E, pS1> const &b)
+ {
+ int n = b.template shape<1>(), m = a.template shape<0>(),
+ k = b.template shape<0>();
+
+ types::ndarray<E, types::array<long, 2>> out(types::array<long, 2>{{m, n}},
+ builtins::None);
+ mm(m, n, k, a.buffer, b.buffer, out.buffer);
+ return out;
+ }
+
+ template <class E, class pS0, class pS1, class pS2>
+ typename std::enable_if<
+ is_blas_type<E>::value && std::tuple_size<pS0>::value == 2 &&
+ std::tuple_size<pS1>::value == 2 && std::tuple_size<pS2>::value == 2,
+ types::ndarray<E, pS2>>::type &
+ dot(types::ndarray<E, pS0> const &a, types::ndarray<E, pS1> const &b,
+ types::ndarray<E, pS2> &c)
+ {
+ int n = b.template shape<1>(), m = a.template shape<0>(),
+ k = b.template shape<0>();
+
+ mm(m, n, k, a.buffer, b.buffer, c.buffer);
+ return c;
+ }
+
+#define TM_DEF(T, L) \
+ inline void tm(int m, int n, int k, T *A, T *B, T *C) \
+ { \
+ cblas_##L##gemm(CblasRowMajor, CblasTrans, CblasNoTrans, m, n, k, 1, A, m, \
+ B, n, 0, C, n); \
+ }
+ TM_DEF(double, d)
+ TM_DEF(float, s)
+#undef TM_DEF
+#define TM_DEF(T, K, L) \
+ inline void tm(int m, int n, int k, T *A, T *B, T *C) \
+ { \
+ T alpha = 1, beta = 0; \
+ cblas_##L##gemm(CblasRowMajor, CblasTrans, CblasNoTrans, m, n, k, \
+ (K *)&alpha, (K *)A, m, (K *)B, n, (K *)&beta, (K *)C, n); \
+ }
+ TM_DEF(std::complex<float>, float, c)
+ TM_DEF(std::complex<double>, double, z)
+#undef TM_DEF
+
+ template <class E, class pS0, class pS1>
+ typename std::enable_if<is_blas_type<E>::value &&
+ std::tuple_size<pS0>::value == 2 &&
+ std::tuple_size<pS1>::value == 2,
+ types::ndarray<E, types::array<long, 2>>>::type
+ dot(types::numpy_texpr<types::ndarray<E, pS0>> const &a,
+ types::ndarray<E, pS1> const &b)
+ {
+ int n = b.template shape<1>(), m = a.template shape<0>(),
+ k = b.template shape<0>();
+
+ types::ndarray<E, types::array<long, 2>> out(types::array<long, 2>{{m, n}},
+ builtins::None);
+ tm(m, n, k, a.arg.buffer, b.buffer, out.buffer);
+ return out;
+ }
+
+#define MT_DEF(T, L) \
+ inline void mt(int m, int n, int k, T *A, T *B, T *C) \
+ { \
+ cblas_##L##gemm(CblasRowMajor, CblasNoTrans, CblasTrans, m, n, k, 1, A, k, \
+ B, k, 0, C, n); \
+ }
+ MT_DEF(double, d)
+ MT_DEF(float, s)
+#undef MT_DEF
+#define MT_DEF(T, K, L) \
+ inline void mt(int m, int n, int k, T *A, T *B, T *C) \
+ { \
+ T alpha = 1, beta = 0; \
+ cblas_##L##gemm(CblasRowMajor, CblasNoTrans, CblasTrans, m, n, k, \
+ (K *)&alpha, (K *)A, k, (K *)B, k, (K *)&beta, (K *)C, n); \
+ }
+ MT_DEF(std::complex<float>, float, c)
+ MT_DEF(std::complex<double>, double, z)
+#undef MT_DEF
+
+ template <class E, class pS0, class pS1>
+ typename std::enable_if<is_blas_type<E>::value &&
+ std::tuple_size<pS0>::value == 2 &&
+ std::tuple_size<pS1>::value == 2,
+ types::ndarray<E, types::array<long, 2>>>::type
+ dot(types::ndarray<E, pS0> const &a,
+ types::numpy_texpr<types::ndarray<E, pS1>> const &b)
+ {
+ int n = b.template shape<1>(), m = a.template shape<0>(),
+ k = b.template shape<0>();
+
+ types::ndarray<E, types::array<long, 2>> out(types::array<long, 2>{{m, n}},
+ builtins::None);
+ mt(m, n, k, a.buffer, b.arg.buffer, out.buffer);
+ return out;
+ }
+
+#define TT_DEF(T, L) \
+ inline void tt(int m, int n, int k, T *A, T *B, T *C) \
+ { \
+ cblas_##L##gemm(CblasRowMajor, CblasTrans, CblasTrans, m, n, k, 1, A, m, \
+ B, k, 0, C, n); \
+ }
+ TT_DEF(double, d)
+ TT_DEF(float, s)
+#undef TT_DEF
+#define TT_DEF(T, K, L) \
+ inline void tt(int m, int n, int k, T *A, T *B, T *C) \
+ { \
+ T alpha = 1, beta = 0; \
+ cblas_##L##gemm(CblasRowMajor, CblasTrans, CblasTrans, m, n, k, \
+ (K *)&alpha, (K *)A, m, (K *)B, k, (K *)&beta, (K *)C, n); \
+ }
+ TT_DEF(std::complex<float>, float, c)
+ TT_DEF(std::complex<double>, double, z)
+#undef TT_DEF
+
+ template <class E, class pS0, class pS1>
+ typename std::enable_if<is_blas_type<E>::value &&
+ std::tuple_size<pS0>::value == 2 &&
+ std::tuple_size<pS1>::value == 2,
+ types::ndarray<E, types::array<long, 2>>>::type
+ dot(types::numpy_texpr<types::ndarray<E, pS0>> const &a,
+ types::numpy_texpr<types::ndarray<E, pS1>> const &b)
+ {
+ int n = b.template shape<1>(), m = a.template shape<0>(),
+ k = b.template shape<0>();
+
+ types::ndarray<E, types::array<long, 2>> out(types::array<long, 2>{{m, n}},
+ builtins::None);
+ tt(m, n, k, a.arg.buffer, b.arg.buffer, out.buffer);
+ return out;
+ }
+
+ // If arguments could be use with blas, we evaluate them as we need pointer
+ // on array for blas
+ template <class E, class F>
+ typename std::enable_if<
+ types::is_numexpr_arg<E>::value &&
+ types::is_numexpr_arg<F>::value // It is an array_like
+ && (!(types::is_ndarray<E>::value && types::is_ndarray<F>::value) ||
+ !std::is_same<typename E::dtype, typename F::dtype>::value) &&
+ is_blas_type<typename E::dtype>::value &&
+ is_blas_type<typename F::dtype>::value // With dtype compatible with
+ // blas
+ && E::value == 2 && F::value == 2, // And both are matrix
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::array<long, 2>>>::type
+ dot(E const &e, F const &f)
+ {
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ typename E::shape_t>
+ e_ = e;
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ typename F::shape_t>
+ f_ = f;
+ return dot(e_, f_);
+ }
+
+ // If one of the arg doesn't have a "blas compatible type", we use a slow
+ // matrix multiplication.
+ template <class E, class F>
+ typename std::enable_if<
+ (!is_blas_type<typename E::dtype>::value ||
+ !is_blas_type<typename F::dtype>::value) &&
+ E::value == 2 && F::value == 2, // And it is matrix / matrix
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::array<long, 2>>>::type
+ dot(E const &e, F const &f)
+ {
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::array<long, 2>>
+ out(types::array<long, 2>{{e.template shape<0>(),
+ f.template shape<1>()}},
+ 0);
+ for (long i = 0; i < out.template shape<0>(); i++)
+ for (long j = 0; j < out.template shape<1>(); j++)
+ for (long k = 0; k < e.template shape<1>(); k++)
+ out[types::array<long, 2>{{i, j}}] +=
+ e[types::array<long, 2>{{i, k}}] *
+ f[types::array<long, 2>{{k, j}}];
+ return out;
+ }
+
+ template <class E, class F>
+ typename std::enable_if<
+ (E::value >= 3 && F::value == 1), // And it is matrix / matrix
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::array<long, E::value - 1>>>::type
+ dot(E const &e, F const &f)
+ {
+ auto out = dot(
+ e.reshape(types::array<long, 2>{{sutils::prod_head(e), f.size()}}), f);
+ types::array<long, E::value - 1> out_shape;
+ auto tmp = sutils::getshape(e);
+ std::copy(tmp.begin(), tmp.end() - 1, out_shape.begin());
+ return out.reshape(out_shape);
+ }
+
+ template <class E, class F>
+ typename std::enable_if<
+ (E::value >= 3 && F::value >= 2),
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::array<long, E::value - 1>>>::type
+ dot(E const &e, F const &f)
+ {
+ static_assert(E::value == 0, "not implemented yet");
+ }
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/double_.hpp b/contrib/python/pythran/pythran/pythonic/numpy/double_.hpp
new file mode 100644
index 00000000000..e5fa42b3de9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/double_.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_NUMPY_DOUBLE_HPP
+#define PYTHONIC_NUMPY_DOUBLE_HPP
+
+#include "pythonic/include/numpy/double_.hpp"
+#include "pythonic/include/numpy/float64.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME double_
+#define NUMPY_NARY_FUNC_SYM details::float64
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/dtype/type.hpp b/contrib/python/pythran/pythran/pythonic/numpy/dtype/type.hpp
new file mode 100644
index 00000000000..894286b9386
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/dtype/type.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_NUMPY_DTYPE_TYPE_HPP
+#define PYTHONIC_NUMPY_DTYPE_TYPE_HPP
+
+#include "pythonic/include/numpy/dtype/type.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace dtype
+ {
+ template <class T, class V>
+ auto type(T const &t, V const &v) -> decltype(t(v))
+ {
+ return t(v);
+ }
+ }
+}
+
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/e.hpp b/contrib/python/pythran/pythran/pythonic/numpy/e.hpp
new file mode 100644
index 00000000000..982ca843fde
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/e.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_NUMPY_E_HPP
+#define PYTHONIC_NUMPY_E_HPP
+
+#include "pythonic/include/numpy/e.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ediff1d.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ediff1d.hpp
new file mode 100644
index 00000000000..cbde610ee5d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ediff1d.hpp
@@ -0,0 +1,34 @@
+#ifndef PYTHONIC_NUMPY_EDIFF1D_HPP
+#define PYTHONIC_NUMPY_EDIFF1D_HPP
+
+#include "pythonic/include/numpy/ediff1d.hpp"
+
+#include "pythonic/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ types::ndarray<typename E::dtype, types::pshape<long>> ediff1d(E const &expr)
+ {
+ auto arr = asarray(expr);
+ long n = arr.flat_size() - 1;
+ types::ndarray<typename E::dtype, types::pshape<long>> out(
+ types::pshape<long>(n), builtins::None);
+ // Compute adjacent difference except for the first element
+ std::adjacent_difference(arr.fbegin() + 1, arr.fend(), out.fbegin());
+ // First element can be done now
+ (*out.fbegin()) = *(arr.fbegin() + 1) - *(arr.fbegin());
+ return out;
+ }
+
+ template <class E>
+ auto ediff1d(types::list<E> const &expr) -> decltype(ediff1d(asarray(expr)))
+ {
+ return ediff1d(asarray(expr));
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/equal.hpp b/contrib/python/pythran/pythran/pythonic/numpy/equal.hpp
new file mode 100644
index 00000000000..ba51ed6d7db
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/equal.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_NUMPY_EQUAL_HPP
+#define PYTHONIC_NUMPY_EQUAL_HPP
+
+#include "pythonic/include/numpy/equal.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/operator_/eq.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME equal
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::eq
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/equal/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/equal/accumulate.hpp
new file mode 100644
index 00000000000..df26c1e9d18
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/equal/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_EQUAL_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_EQUAL_ACCUMULATE_HPP
+
+#define UFUNC_NAME equal
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/expm1.hpp b/contrib/python/pythran/pythran/pythonic/numpy/expm1.hpp
new file mode 100644
index 00000000000..eee79f19ac4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/expm1.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_NUMPY_EXPM1_HPP
+#define PYTHONIC_NUMPY_EXPM1_HPP
+
+#include "pythonic/include/numpy/expm1.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME expm1
+#define NUMPY_NARY_FUNC_SYM xsimd::expm1
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/eye.hpp b/contrib/python/pythran/pythran/pythonic/numpy/eye.hpp
new file mode 100644
index 00000000000..8bed2d4a339
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/eye.hpp
@@ -0,0 +1,38 @@
+#ifndef PYTHONIC_NUMPY_EYE_HPP
+#define PYTHONIC_NUMPY_EYE_HPP
+
+#include "pythonic/include/numpy/eye.hpp"
+
+#include "pythonic/numpy/zeros.hpp"
+#include "pythonic/builtins/None.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class dtype>
+ types::ndarray<typename dtype::type, types::array<long, 2>>
+ eye(long N, long M, long k, dtype d)
+ {
+ types::ndarray<typename dtype::type, types::array<long, 2>> out =
+ zeros(types::make_tuple(N, M), d);
+ if (k >= 0)
+ for (int i = 0, j = k; i < N && j < M; ++i, ++j)
+ out[i][j] = typename dtype::type(1);
+ else
+ for (int i = -k, j = 0; i < N && j < M; ++i, ++j)
+ out[i][j] = typename dtype::type(1);
+ return out;
+ }
+
+ template <class dtype>
+ types::ndarray<typename dtype::type, types::array<long, 2>>
+ eye(long N, types::none_type M, long k, dtype d)
+ {
+ return eye(N, N, k, d);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fabs.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fabs.hpp
new file mode 100644
index 00000000000..109a24f9586
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fabs.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_FABS_HPP
+#define PYTHONIC_NUMPY_FABS_HPP
+
+#include "pythonic/include/numpy/fabs.hpp"
+#include "pythonic/numpy/abs.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fft/c2c.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fft/c2c.hpp
new file mode 100644
index 00000000000..aae6de63158
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fft/c2c.hpp
@@ -0,0 +1,310 @@
+#ifndef PYTHONIC_NUMPY_FFT_C2C_HPP
+#define PYTHONIC_NUMPY_FFT_C2C_HPP
+
+#include "pythonic/include/numpy/fft/c2c.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/include/utils/array_helper.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/numpy/concatenate.hpp"
+#include "pythonic/numpy/zeros.hpp"
+#include "pythonic/numpy/empty.hpp"
+
+#include <array>
+#include <cstring>
+#include <cmath>
+
+#include "pythonic/numpy/fft/pocketfft.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace fft
+ {
+ using pocketfft::stride_t;
+ using pocketfft::shape_t;
+ using ldbl_t =
+ typename std::conditional<sizeof(long double) == sizeof(double), double,
+ long double>::type;
+
+ template <class T, class pS>
+ types::ndarray<
+ typename std::enable_if<std::is_integral<T>::value, double>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ _copy_to_double(types::ndarray<T, pS> const &in_array)
+ {
+ auto out_shape = sutils::getshape(in_array);
+ size_t l = in_array.flat_size();
+ auto out_array = numpy::empty(out_shape, types::dtype_t<double>());
+ std::copy(in_array.buffer, in_array.buffer + l, out_array.buffer);
+ return out_array;
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ _copy_to_complex(types::ndarray<T, pS> const &in_array)
+ {
+ auto out_shape = sutils::getshape(in_array);
+ size_t l = in_array.flat_size();
+ auto out_array =
+ numpy::empty(out_shape, types::dtype_t<typename std::complex<T>>());
+ std::copy(in_array.buffer, in_array.buffer + l, out_array.buffer);
+ return out_array;
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ _copy_to_complex(types::ndarray<T, pS> const &in_array)
+ {
+ auto out_shape = sutils::getshape(in_array);
+ size_t l = in_array.flat_size();
+ auto out_array = numpy::empty(
+ out_shape, types::dtype_t<typename std::complex<double>>());
+ std::copy(in_array.buffer, in_array.buffer + l, out_array.buffer);
+ return out_array;
+ }
+
+ enum class Inorm : int {
+ forward,
+ explicit_forward,
+ ortho,
+ backward,
+ };
+
+ Inorm _get_inorm(types::str const &norm, bool forward)
+ {
+ if (norm == "ortho")
+ return Inorm::ortho;
+ if (norm == "forward")
+ return Inorm::explicit_forward;
+ return forward ? Inorm::forward : Inorm::backward;
+ }
+
+ template <typename T>
+ T norm_fct(Inorm inorm, size_t N)
+ {
+ switch (inorm) {
+ case Inorm::ortho:
+ return T(1 / sqrt(ldbl_t(N)));
+ case Inorm::backward:
+ return T(1 / ldbl_t(N));
+ case Inorm::explicit_forward:
+ return T(1./N);
+ default:
+ assert(false && "unreachable");
+ return T(0);
+ }
+ }
+
+ template <typename T>
+ T norm_fct(Inorm inorm, const shape_t &shape, const shape_t &axes,
+ size_t fct = 1, int delta = 0)
+ {
+ // Fast path
+ if (inorm == Inorm::forward)
+ return 1;
+
+ size_t N(1);
+ for (auto a : axes)
+ N *= fct * size_t(int64_t(shape[a]) + delta);
+ return norm_fct<T>(inorm, N);
+ }
+
+ template <class T, class pS>
+ stride_t create_strides(types::ndarray<T, pS> const &in_array)
+ {
+ auto constexpr N = std::tuple_size<pS>::value;
+ auto shape = sutils::getshape(in_array);
+ stride_t strides = stride_t(N);
+ strides[N - 1] = sizeof(T);
+ std::transform(strides.rbegin(), strides.rend() - 1, shape.rbegin(),
+ strides.rbegin() + 1, std::multiplies<long>());
+ return strides;
+ }
+
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ _pad_in_array(types::ndarray<T, pS> const &in_array, long axis, long n)
+ {
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ extended_array;
+ auto tmp_shape = sutils::getshape(in_array);
+ tmp_shape[axis] = n;
+ auto tmp_array = zeros(tmp_shape, types::dtype_t<T>());
+ types::list<types::ndarray<
+ T, types::array<long, std::tuple_size<pS>::value>>> bi(0);
+ bi.push_back(in_array);
+ bi.push_back(tmp_array);
+ extended_array = concatenate(bi, axis);
+ return extended_array;
+ }
+
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ c2r(types::ndarray<std::complex<T>, pS> const &in_array, long n, long axis,
+ types::str const &norm, bool forward)
+ {
+ auto constexpr N = std::tuple_size<pS>::value;
+ Inorm inorm = _get_inorm(norm, forward);
+ if (axis < 0)
+ axis = N + axis;
+ auto in_shape = sutils::getshape(in_array);
+ long npts = in_shape[axis];
+ if (n == -1)
+ n = 2 * npts - 2;
+ auto out_shape = sutils::getshape(in_array);
+ out_shape[axis] = n;
+ // Create output array.
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ out_array(out_shape, builtins::None);
+ std::complex<T> *d_in;
+ types::ndarray<std::complex<T>,
+ types::array<long, std::tuple_size<pS>::value>>
+ extended_array;
+ stride_t in_strides;
+ auto out_strides = create_strides(out_array);
+ if (n > 2 * npts - 2) {
+ // extend array with zeros along axis direction
+ extended_array = _pad_in_array(in_array, axis, n - (2 * npts - 2));
+ in_strides = create_strides(extended_array);
+ d_in = reinterpret_cast<std::complex<T> *>(extended_array.buffer);
+ } else {
+ in_strides = create_strides(
+ in_array); // for cropped arrays we need to use different strides
+ d_in = reinterpret_cast<std::complex<T> *>(in_array.buffer);
+ }
+ auto d_out = reinterpret_cast<T *>(out_array.buffer);
+ // axes calculation is for 1D transform
+ shape_t axes = shape_t(1);
+ axes[0] = axis;
+ shape_t shapes = shape_t(size_t(N));
+ std::copy(out_shape.begin(), out_shape.begin() + N, shapes.begin());
+ auto fct = norm_fct<T>(inorm, shapes, axes);
+ pocketfft::c2r(shapes, in_strides, out_strides, axes, forward, d_in,
+ d_out, fct, size_t(0));
+ return out_array;
+ }
+
+ template <class T, class pS>
+ types::ndarray<std::complex<T>,
+ types::array<long, std::tuple_size<pS>::value>>
+ c2c(types::ndarray<std::complex<T>, pS> const &in_array, long n, long axis,
+ types::str const &norm, bool forward)
+ {
+ auto constexpr N = std::tuple_size<pS>::value;
+ Inorm inorm = _get_inorm(norm, forward);
+ if (axis < 0)
+ axis = N + axis;
+ auto in_shape = sutils::getshape(in_array);
+ long npts = in_shape[axis];
+ if (n == -1)
+ n = npts;
+ auto out_shape = sutils::getshape(in_array);
+ out_shape[axis] = n;
+ // Create output array.
+ types::ndarray<std::complex<T>,
+ types::array<long, std::tuple_size<pS>::value>>
+ out_array(out_shape, builtins::None);
+ std::complex<T> *d_in;
+ types::ndarray<std::complex<T>,
+ types::array<long, std::tuple_size<pS>::value>>
+ extended_array;
+ stride_t in_strides;
+ if (n > npts) {
+ // extend array with zeros along axis direction
+ extended_array = _pad_in_array(in_array, axis, n - npts);
+ d_in = reinterpret_cast<std::complex<T> *>(extended_array.buffer);
+ in_strides = create_strides(extended_array); //
+ } else {
+ d_in = reinterpret_cast<std::complex<T> *>(in_array.buffer);
+ in_strides = create_strides(
+ in_array); // for cropped arrays we need to use different strides
+ }
+ auto d_out = reinterpret_cast<std::complex<T> *>(out_array.buffer);
+ // axes calculation is for 1D transform
+ shape_t axes = shape_t(1);
+ axes[0] = axis;
+ auto out_strides = create_strides(out_array);
+ shape_t shapes = shape_t(size_t(N));
+ for (size_t i = 0; i < N; ++i)
+ shapes[i] = size_t(out_shape[i]);
+ auto fct = norm_fct<T>(inorm, shapes, axes);
+ pocketfft::c2c(shapes, in_strides, out_strides, axes, forward, d_in,
+ d_out, fct, size_t(0));
+ return out_array;
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ r2c(types::ndarray<T, pS> const &in_array, long n, long axis,
+ types::str const &norm, bool forward, bool extend = true)
+ {
+ auto constexpr N = std::tuple_size<pS>::value;
+ Inorm inorm = _get_inorm(norm, forward);
+ if (axis < 0)
+ axis = N + axis;
+ auto in_shape = sutils::getshape(in_array);
+ long npts = in_shape[axis];
+ if (n == -1)
+ n = npts;
+ auto out_shape = sutils::getshape(in_array);
+ if (extend) {
+ out_shape[axis] = n;
+ } else {
+ out_shape[axis] = n / 2 + 1;
+ }
+ // Create output array.
+ types::ndarray<std::complex<T>,
+ types::array<long, std::tuple_size<pS>::value>>
+ out_array(out_shape, builtins::None);
+ T *d_in;
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ extended_array;
+ shape_t shapes = shape_t(size_t(N));
+ stride_t in_strides;
+ if (n > npts) {
+ // extend array with zeros along axis direction
+ extended_array = _pad_in_array(in_array, axis, n - npts);
+ auto ext_shape = sutils::getshape(extended_array);
+ std::copy(ext_shape.begin(), ext_shape.begin() + N, shapes.begin());
+ d_in = reinterpret_cast<T *>(extended_array.buffer);
+ in_strides = create_strides(extended_array);
+ } else {
+ d_in = reinterpret_cast<T *>(in_array.buffer);
+ in_shape[axis] = n;
+ std::copy(in_shape.begin(), in_shape.begin() + N, shapes.begin());
+ in_strides = create_strides(
+ in_array); // for cropped arrays we need to use different strides
+ }
+ auto d_out = reinterpret_cast<std::complex<T> *>(out_array.buffer);
+ // axes calculation is for 1D transform
+ shape_t axes = shape_t(1);
+ axes[0] = axis;
+ auto out_strides = create_strides(out_array);
+ auto fct = norm_fct<T>(inorm, shapes, axes);
+ pocketfft::r2c(shapes, in_strides, out_strides, axes, forward, d_in,
+ d_out, fct, size_t(0));
+ if (extend) {
+ using namespace pocketfft::detail;
+ ndarr<std::complex<T>> ares(out_array.buffer, shapes, out_strides);
+ rev_iter iter(ares, axes);
+ while (iter.remaining() > 0) {
+ auto v = ares[iter.ofs()];
+ ares[iter.rev_ofs()] = conj(v);
+ iter.advance();
+ }
+ }
+ return out_array;
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fft/fft.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fft/fft.hpp
new file mode 100644
index 00000000000..d8eed26b823
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fft/fft.hpp
@@ -0,0 +1,77 @@
+#ifndef PYTHONIC_NUMPY_FFT_FFT_HPP
+#define PYTHONIC_NUMPY_FFT_FFT_HPP
+
+#include "pythonic/include/numpy/fft/fft.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/include/utils/array_helper.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/numpy/fft/c2c.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace fft
+ {
+ namespace details
+ {
+ inline types::str normalize_norm(types::none_type const &)
+ {
+ return "backward";
+ }
+
+ template <class T>
+ inline types::str normalize_norm(T const &norm)
+ {
+ return norm;
+ }
+
+ inline long normalize_n(types::none_type const &)
+ {
+ return -1;
+ }
+
+ inline long normalize_n(long const &n)
+ {
+ return n;
+ }
+ }
+
+ template <class T, class pS, class N, class Norm>
+ types::ndarray<
+ typename std::enable_if<types::is_complex<T>::value, T>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ fft(types::ndarray<T, pS> const &in_array, N const& n, long axis,
+ Norm const &norm)
+ {
+ return c2c(in_array, details::normalize_n(n), axis, details::normalize_norm(norm), true);
+ }
+
+ template <class T, class pS, class N, class Norm>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ fft(types::ndarray<T, pS> const &in_array, N const & n, long axis,
+ Norm const &norm)
+ {
+ return r2c(in_array, details::normalize_n(n), axis, details::normalize_norm(norm), true, true);
+ }
+
+ template <class T, class pS, class N, class Norm>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ fft(types::ndarray<T, pS> const &in_array, N const& n, long axis,
+ Norm const &norm)
+ {
+ auto tmp_array = _copy_to_double(in_array);
+ return fft(tmp_array, n, axis, norm);
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(fft);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fft/fftn.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fft/fftn.hpp
new file mode 100644
index 00000000000..37cf60a7483
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fft/fftn.hpp
@@ -0,0 +1,145 @@
+#ifndef PYTHONIC_NUMPY_FFT_FFTN_HPP
+#define PYTHONIC_NUMPY_FFT_FFTN_HPP
+
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/include/numpy/fft/fftn.hpp"
+#include "pythonic/include/utils/array_helper.hpp"
+#include "pythonic/numpy/fft/c2c.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace fft
+ {
+ namespace details
+ {
+ inline types::str normalize_norm(types::none_type const &)
+ {
+ return "backward";
+ }
+ template <class T>
+ inline types::str normalize_norm(T const &norm)
+ {
+ return norm;
+ }
+
+ template <size_t K, size_t S>
+ types::array < long,
+ K<S ? K : S> normalize_axes(types::none_type const &)
+ {
+ if (S == 1)
+ return {-1}; // FIXME: understand why this is needed
+ types::array < long, K<S ? K : S> result;
+ for (size_t i = 0; i < std::min(K, S); ++i)
+ result[i] = (long)i;
+ return result;
+ }
+ template <size_t K, size_t S, class T, size_t N, class V>
+ types::array_base<T, N, V> const &
+ normalize_axes(types::array_base<T, N, V> const &axes)
+ {
+ return axes;
+ }
+ } // namespace details
+
+ // without shape
+
+ template <class T, class pS, class Axes, class Norm>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ fftn(types::ndarray<T, pS> const &in_array, types::none_type s,
+ Axes const &axes, Norm const &norm)
+ {
+ auto tmp_array = _copy_to_double(in_array);
+ return fftn(tmp_array, s, axes, norm);
+ }
+
+ template <class T, class pS, class Axes, class Norm>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ fftn(types::ndarray<T, pS> const &in_array, types::none_type s,
+ Axes const &axes, Norm const &norm)
+ {
+ auto naxes = details::normalize_axes<std::tuple_size<pS>::value, 1>(axes);
+ auto nnorm = details::normalize_norm(norm);
+ auto result = r2c(in_array, -1, naxes[0], nnorm.c_str(), true, true);
+ for (size_t i = 1; i < naxes.size(); ++i)
+ result = c2c(result, -1, naxes[i], nnorm.c_str(), true);
+ return result;
+ }
+
+ template <class T, class pS, class Axes, class Norm>
+ types::ndarray<
+ typename std::enable_if<types::is_complex<T>::value, T>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ fftn(types::ndarray<T, pS> const &in_array, types::none_type s,
+ Axes const &axes, Norm const &norm)
+ {
+ auto naxes = details::normalize_axes<std::tuple_size<pS>::value, 1>(axes);
+ auto nnorm = details::normalize_norm(norm);
+ auto result = c2c(in_array, -1, naxes[0], nnorm.c_str(), true);
+ for (size_t i = 1; i < naxes.size(); ++i)
+ result = c2c(result, -1, naxes[i], nnorm.c_str(), true);
+ return result;
+ }
+
+ // with shape
+ template <class T, class pS, class I, size_t N, class V, class Axes,
+ class Norm>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ fftn(types::ndarray<T, pS> const &a, types::array_base<I, N, V> const &s,
+ Axes const &axes, Norm const &norm)
+ {
+ auto tmp_array = _copy_to_double(a);
+ return fftn(tmp_array, s, axes, norm);
+ }
+
+ template <class T, class pS, class I, size_t N, class V, class Axes,
+ class Norm>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ fftn(types::ndarray<T, pS> const &a, types::array_base<I, N, V> const &s,
+ Axes const &axes, Norm const &norm)
+ {
+ auto nnorm = details::normalize_norm(norm);
+ auto naxes = details::normalize_axes<std::tuple_size<pS>::value, N>(axes);
+ size_t i = 0;
+ auto out = r2c(a, s[i], naxes[i], nnorm.c_str(), true, true);
+ for (++i; i < N; ++i) {
+ out = c2c(out, s[i], naxes[i], nnorm.c_str(), true);
+ }
+ return out;
+ }
+
+ template <class T, class pS, class I, size_t N, class V, class Axes,
+ class Norm>
+ types::ndarray<
+ typename std::enable_if<types::is_complex<T>::value, T>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ fftn(types::ndarray<T, pS> const &a, types::array_base<I, N, V> const &s,
+ Axes const &axes, Norm const &norm)
+ {
+ auto nnorm = details::normalize_norm(norm);
+ auto naxes = details::normalize_axes<std::tuple_size<pS>::value, N>(axes);
+ size_t i = 0;
+ auto out = c2c(a, s[i], naxes[i], nnorm.c_str(), true);
+ for (++i; i < N; ++i) {
+ out = c2c(out, s[i], naxes[i], nnorm.c_str(), true);
+ }
+ return out;
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(fftn);
+ } // namespace fft
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fft/hfft.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fft/hfft.hpp
new file mode 100644
index 00000000000..3820ba44a11
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fft/hfft.hpp
@@ -0,0 +1,107 @@
+#ifndef PYTHONIC_NUMPY_FFT_HFFT_HPP
+#define PYTHONIC_NUMPY_FFT_HFFT_HPP
+
+#include "pythonic/include/numpy/fft/hfft.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/include/utils/array_helper.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/numpy/fft/c2c.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace fft
+ {
+
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ hfft(types::ndarray<std::complex<T>, pS> const &in_array,
+ types::none_type n, long axis, types::str const &norm)
+ {
+ return c2r(in_array, -1, axis, norm, true);
+ }
+
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ hfft(types::ndarray<std::complex<T>, pS> const &in_array,
+ types::none_type n, long axis, types::none_type norm)
+ {
+ return c2r(in_array, -1, axis, "", true);
+ }
+
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ hfft(types::ndarray<std::complex<T>, pS> const &in_array, long n, long axis,
+ types::none_type norm)
+ {
+ return c2r(in_array, n, axis, "", true);
+ }
+
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ hfft(types::ndarray<std::complex<T>, pS> const &in_array, long n, long axis,
+ types::str const &norm)
+ {
+ return c2r(in_array, n, axis, norm, true);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<
+ !types::is_complex<T>::value,
+ typename std::conditional<std::is_integral<T>::value,
+ double, T>::type>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ hfft(types::ndarray<T, pS> const &in_array, types::none_type n, long axis,
+ types::str const &norm)
+ {
+ auto tmp_array = _copy_to_complex(in_array);
+ return c2r(tmp_array, -1, axis, norm, true);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<
+ !types::is_complex<T>::value,
+ typename std::conditional<std::is_integral<T>::value,
+ double, T>::type>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ hfft(types::ndarray<T, pS> const &in_array, types::none_type n, long axis,
+ types::none_type norm)
+ {
+ auto tmp_array = _copy_to_complex(in_array);
+ return c2r(tmp_array, -1, axis, "", true);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<
+ !types::is_complex<T>::value,
+ typename std::conditional<std::is_integral<T>::value,
+ double, T>::type>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ hfft(types::ndarray<T, pS> const &in_array, long n, long axis,
+ types::none_type norm)
+ {
+ auto tmp_array = _copy_to_complex(in_array);
+ return c2r(tmp_array, n, axis, "", true);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<
+ !types::is_complex<T>::value,
+ typename std::conditional<std::is_integral<T>::value,
+ double, T>::type>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ hfft(types::ndarray<T, pS> const &in_array, long n, long axis,
+ types::str const &norm)
+ {
+ auto tmp_array = _copy_to_complex(in_array);
+ return c2r(tmp_array, n, axis, norm, true);
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(hfft);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fft/ifft.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fft/ifft.hpp
new file mode 100644
index 00000000000..23aad1d0c77
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fft/ifft.hpp
@@ -0,0 +1,147 @@
+#ifndef PYTHONIC_NUMPY_FFT_IFFT_HPP
+#define PYTHONIC_NUMPY_FFT_IFFT_HPP
+
+#include "pythonic/include/numpy/fft/ifft.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/include/utils/array_helper.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/numpy/fft/c2c.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace fft
+ {
+
+ template <class T, class pS>
+ types::ndarray<
+ typename std::enable_if<types::is_complex<T>::value, T>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &in_array, types::none_type n, long axis,
+ types::str const &norm)
+ {
+ return c2c(in_array, -1, axis, norm, false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<
+ typename std::enable_if<types::is_complex<T>::value, T>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &in_array, types::none_type n, long axis,
+ types::none_type norm)
+ {
+ return c2c(in_array, -1, axis, "", false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<
+ typename std::enable_if<types::is_complex<T>::value, T>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &in_array, long n, long axis,
+ types::none_type norm)
+ {
+ return c2c(in_array, n, axis, "", false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<
+ typename std::enable_if<types::is_complex<T>::value, T>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &in_array, long n, long axis,
+ types::str const &norm)
+ {
+ return c2c(in_array, n, axis, norm, false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &in_array, types::none_type n, long axis,
+ types::str const &norm)
+ {
+ return r2c(in_array, -1, axis, norm, false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &in_array, types::none_type n, long axis,
+ types::none_type norm)
+ {
+ return r2c(in_array, -1, axis, "", false, true);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &in_array, long n, long axis,
+ types::none_type norm)
+ {
+ return r2c(in_array, n, axis, "", false, true);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &in_array, long n, long axis,
+ types::str const &norm)
+ {
+ return r2c(in_array, n, axis, norm, false, true);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &in_array, types::none_type n, long axis,
+ types::str const &norm)
+ {
+ auto tmp_array = _copy_to_double(in_array);
+ return r2c(tmp_array, -1, axis, norm, false, true);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &in_array, types::none_type n, long axis,
+ types::none_type norm)
+ {
+ auto tmp_array = _copy_to_double(in_array);
+ return r2c(tmp_array, -1, axis, "", false, true);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &in_array, long n, long axis,
+ types::none_type norm)
+ {
+ auto tmp_array = _copy_to_double(in_array);
+ return r2c(tmp_array, n, axis, "", false, true);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ifft(types::ndarray<T, pS> const &in_array, long n, long axis,
+ types::str const &norm)
+ {
+ auto tmp_array = _copy_to_double(in_array);
+ return r2c(tmp_array, n, axis, norm, false, true);
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(ifft);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fft/ihfft.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fft/ihfft.hpp
new file mode 100644
index 00000000000..44fe008bb53
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fft/ihfft.hpp
@@ -0,0 +1,106 @@
+#ifndef PYTHONIC_NUMPY_FFT_IHFFT_HPP
+#define PYTHONIC_NUMPY_FFT_IHFFT_HPP
+#include "pythonic/include/numpy/fft/ihfft.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/include/utils/array_helper.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/numpy/fft/c2c.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace fft
+ {
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ihfft(types::ndarray<T, pS> const &in_array, types::none_type n, long axis,
+ types::str const &norm)
+ {
+ return r2c(in_array, -1, axis, norm, false, false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ihfft(types::ndarray<T, pS> const &in_array, types::none_type n, long axis,
+ types::none_type norm)
+ {
+ return r2c(in_array, -1, axis, "", false, false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ihfft(types::ndarray<T, pS> const &in_array, long n, long axis,
+ types::none_type norm)
+ {
+ return r2c(in_array, n, axis, "", false, false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ihfft(types::ndarray<T, pS> const &in_array, long n, long axis,
+ types::str const &norm)
+ {
+ return r2c(in_array, n, axis, norm, false, false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ihfft(types::ndarray<T, pS> const &in_array, types::none_type n, long axis,
+ types::str const &norm)
+ {
+ auto tmp_array = _copy_to_double(in_array);
+ return r2c(tmp_array, -1, axis, norm, false, false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ihfft(types::ndarray<T, pS> const &in_array, types::none_type n, long axis,
+ types::none_type norm)
+ {
+ auto tmp_array = _copy_to_double(in_array);
+ return r2c(tmp_array, -1, axis, "", false, false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ihfft(types::ndarray<T, pS> const &in_array, long n, long axis,
+ types::none_type norm)
+ {
+ auto tmp_array = _copy_to_double(in_array);
+ return r2c(tmp_array, n, axis, "", false, false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ ihfft(types::ndarray<T, pS> const &in_array, long n, long axis,
+ types::str const &norm)
+ {
+ auto tmp_array = _copy_to_double(in_array);
+ return r2c(tmp_array, n, axis, norm, false, false);
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(ihfft);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fft/irfft.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fft/irfft.hpp
new file mode 100644
index 00000000000..acc24765e24
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fft/irfft.hpp
@@ -0,0 +1,107 @@
+#ifndef PYTHONIC_NUMPY_FFT_IRFFT_HPP
+#define PYTHONIC_NUMPY_FFT_IRFFT_HPP
+
+#include "pythonic/include/numpy/fft/irfft.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/include/utils/array_helper.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/numpy/fft/c2c.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace fft
+ {
+
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ irfft(types::ndarray<std::complex<T>, pS> const &in_array,
+ types::none_type n, long axis, types::str const &norm)
+ {
+ return c2r(in_array, -1, axis, norm, false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ irfft(types::ndarray<std::complex<T>, pS> const &in_array,
+ types::none_type n, long axis, types::none_type norm)
+ {
+ return c2r(in_array, -1, axis, "", false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ irfft(types::ndarray<std::complex<T>, pS> const &in_array, long n,
+ long axis, types::none_type norm)
+ {
+ return c2r(in_array, n, axis, "", false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ irfft(types::ndarray<std::complex<T>, pS> const &in_array, long n,
+ long axis, types::str const &norm)
+ {
+ return c2r(in_array, n, axis, norm, false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<
+ !types::is_complex<T>::value,
+ typename std::conditional<std::is_integral<T>::value,
+ double, T>::type>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ irfft(types::ndarray<T, pS> const &in_array, types::none_type n, long axis,
+ types::str const &norm)
+ {
+ auto tmp_array = _copy_to_complex(in_array);
+ return c2r(tmp_array, -1, axis, norm, false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<
+ !types::is_complex<T>::value,
+ typename std::conditional<std::is_integral<T>::value,
+ double, T>::type>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ irfft(types::ndarray<T, pS> const &in_array, types::none_type n, long axis,
+ types::none_type norm)
+ {
+ auto tmp_array = _copy_to_complex(in_array);
+ return c2r(tmp_array, -1, axis, "", false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<
+ !types::is_complex<T>::value,
+ typename std::conditional<std::is_integral<T>::value,
+ double, T>::type>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ irfft(types::ndarray<T, pS> const &in_array, long n, long axis,
+ types::none_type norm)
+ {
+ auto tmp_array = _copy_to_complex(in_array);
+ return c2r(tmp_array, n, axis, "", false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<
+ !types::is_complex<T>::value,
+ typename std::conditional<std::is_integral<T>::value,
+ double, T>::type>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ irfft(types::ndarray<T, pS> const &in_array, long n, long axis,
+ types::str const &norm)
+ {
+ auto tmp_array = _copy_to_complex(in_array);
+ return c2r(tmp_array, n, axis, norm, false);
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(irfft);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fft/pocketfft.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fft/pocketfft.hpp
new file mode 100644
index 00000000000..be696d0d3dc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fft/pocketfft.hpp
@@ -0,0 +1,3933 @@
+/*
+This file is part of pocketfft.
+
+Copyright (C) 2010-2019 Max-Planck-Society
+Copyright (C) 2019 Peter Bell
+
+For the odd-sized DCT-IV transforms:
+ Copyright (C) 2003, 2007-14 Matteo Frigo
+ Copyright (C) 2003, 2007-14 Massachusetts Institute of Technology
+
+Authors: Martin Reinecke, Peter Bell
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or
+ other materials provided with the distribution.
+* Neither the name of the copyright holder nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef PYTHONIC_INCLUDE_NUMPY_FFT_POCKETFFT_HPP
+#define PYTHONIC_INCLUDE_NUMPY_FFT_POCKETFFT_HPP
+#ifndef POCKETFFT_HDRONLY_H
+#define POCKETFFT_HDRONLY_H
+
+#ifndef __cplusplus
+#error This file is C++ and requires a C++ compiler.
+#endif
+
+#if !(__cplusplus >= 201103L || _MSVC_LANG + 0L >= 201103L)
+#error This file requires at least C++11 support.
+#endif
+
+#ifndef POCKETFFT_CACHE_SIZE
+#define POCKETFFT_CACHE_SIZE 16
+#endif
+
+#include <cmath>
+#include <cstring>
+#include <cstdlib>
+#include <stdexcept>
+#include <memory>
+#include <vector>
+#include <complex>
+#if POCKETFFT_CACHE_SIZE != 0
+#include <array>
+#include <mutex>
+#endif
+
+#ifndef POCKETFFT_NO_MULTITHREADING
+#include <mutex>
+#include <condition_variable>
+#include <thread>
+#include <queue>
+#include <atomic>
+#include <functional>
+
+#ifdef POCKETFFT_PTHREADS
+#include <pthread.h>
+#endif
+#endif
+
+#if defined(__GNUC__)
+#define POCKETFFT_NOINLINE __attribute__((noinline))
+#define POCKETFFT_RESTRICT __restrict__
+#elif defined(_MSC_VER)
+#define POCKETFFT_NOINLINE __declspec(noinline)
+#define POCKETFFT_RESTRICT __restrict
+#else
+#define POCKETFFT_NOINLINE
+#define POCKETFFT_RESTRICT
+#endif
+
+namespace pocketfft
+{
+
+ namespace detail
+ {
+ using std::size_t;
+ using std::ptrdiff_t;
+
+ // Always use std:: for <cmath> functions
+ template <typename T>
+ T cos(T) = delete;
+ template <typename T>
+ T sin(T) = delete;
+ template <typename T>
+ T sqrt(T) = delete;
+
+ using shape_t = std::vector<size_t>;
+ using stride_t = std::vector<ptrdiff_t>;
+
+ constexpr bool FORWARD = true, BACKWARD = false;
+
+// only enable vector support for gcc>=5.0 and clang>=5.0
+#ifndef POCKETFFT_NO_VECTORS
+#define POCKETFFT_NO_VECTORS
+#if defined(__INTEL_COMPILER)
+// do nothing. This is necessary because this compiler also sets __GNUC__.
+#elif defined(__clang__)
+// AppleClang has their own version numbering
+#ifdef __apple_build_version__
+#if (__clang_major__ > 9) || (__clang_major__ == 9 && __clang_minor__ >= 1)
+#undef POCKETFFT_NO_VECTORS
+#endif
+#elif __clang_major__ >= 5
+#undef POCKETFFT_NO_VECTORS
+#endif
+#elif defined(__GNUC__)
+#if __GNUC__ >= 5
+#undef POCKETFFT_NO_VECTORS
+#endif
+#endif
+#endif
+
+ template <typename T>
+ struct VLEN {
+ static constexpr size_t val = 1;
+ };
+
+#ifndef POCKETFFT_NO_VECTORS
+#if (defined(__AVX512F__))
+ template <>
+ struct VLEN<float> {
+ static constexpr size_t val = 16;
+ };
+ template <>
+ struct VLEN<double> {
+ static constexpr size_t val = 8;
+ };
+#elif(defined(__AVX__))
+ template <>
+ struct VLEN<float> {
+ static constexpr size_t val = 8;
+ };
+ template <>
+ struct VLEN<double> {
+ static constexpr size_t val = 4;
+ };
+#elif(defined(__SSE2__))
+ template <>
+ struct VLEN<float> {
+ static constexpr size_t val = 4;
+ };
+ template <>
+ struct VLEN<double> {
+ static constexpr size_t val = 2;
+ };
+#elif(defined(__VSX__))
+ template <>
+ struct VLEN<float> {
+ static constexpr size_t val = 4;
+ };
+ template <>
+ struct VLEN<double> {
+ static constexpr size_t val = 2;
+ };
+#else
+#define POCKETFFT_NO_VECTORS
+#endif
+#endif
+
+ template <typename T>
+ class arr
+ {
+ private:
+ T *p;
+ size_t sz;
+
+#if defined(POCKETFFT_NO_VECTORS)
+ static T *ralloc(size_t num)
+ {
+ if (num == 0)
+ return nullptr;
+ void *res = malloc(num * sizeof(T));
+ if (!res)
+ throw std::bad_alloc();
+ return reinterpret_cast<T *>(res);
+ }
+ static void dealloc(T *ptr)
+ {
+ free(ptr);
+ }
+// C++17 in principle has "aligned_alloc", but unfortunately not everywhere ...
+#elif(__cplusplus >= 201703L) && \
+ ((!defined(__MINGW32__)) || defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)) && \
+ (!defined(__APPLE__))
+ static T *ralloc(size_t num)
+ {
+ if (num == 0)
+ return nullptr;
+ void *res = aligned_alloc(64, num * sizeof(T));
+ if (!res)
+ throw std::bad_alloc();
+ return reinterpret_cast<T *>(res);
+ }
+ static void dealloc(T *ptr)
+ {
+ free(ptr);
+ }
+#else // portable emulation
+ static T *ralloc(size_t num)
+ {
+ if (num == 0)
+ return nullptr;
+ void *ptr = malloc(num * sizeof(T) + 64);
+ if (!ptr)
+ throw std::bad_alloc();
+ T *res = reinterpret_cast<T *>(
+ (reinterpret_cast<size_t>(ptr) & ~(size_t(63))) + 64);
+ (reinterpret_cast<void **>(res))[-1] = ptr;
+ return res;
+ }
+ static void dealloc(T *ptr)
+ {
+ if (ptr)
+ free((reinterpret_cast<void **>(ptr))[-1]);
+ }
+#endif
+
+ public:
+ arr() : p(0), sz(0)
+ {
+ }
+ arr(size_t n) : p(ralloc(n)), sz(n)
+ {
+ }
+ arr(arr &&other) : p(other.p), sz(other.sz)
+ {
+ other.p = nullptr;
+ other.sz = 0;
+ }
+ ~arr()
+ {
+ dealloc(p);
+ }
+
+ void resize(size_t n)
+ {
+ if (n == sz)
+ return;
+ dealloc(p);
+ p = ralloc(n);
+ sz = n;
+ }
+
+ T &operator[](size_t idx)
+ {
+ return p[idx];
+ }
+ const T &operator[](size_t idx) const
+ {
+ return p[idx];
+ }
+
+ T *data()
+ {
+ return p;
+ }
+ const T *data() const
+ {
+ return p;
+ }
+
+ size_t size() const
+ {
+ return sz;
+ }
+ };
+
+ template <typename T>
+ struct cmplx {
+ T r, i;
+ cmplx()
+ {
+ }
+ cmplx(T r_, T i_) : r(r_), i(i_)
+ {
+ }
+ void Set(T r_, T i_)
+ {
+ r = r_;
+ i = i_;
+ }
+ void Set(T r_)
+ {
+ r = r_;
+ i = T(0);
+ }
+ cmplx &operator+=(const cmplx &other)
+ {
+ r += other.r;
+ i += other.i;
+ return *this;
+ }
+ template <typename T2>
+ cmplx &operator*=(T2 other)
+ {
+ r *= other;
+ i *= other;
+ return *this;
+ }
+ template <typename T2>
+ cmplx &operator*=(const cmplx<T2> &other)
+ {
+ T tmp = r * other.r - i * other.i;
+ i = r * other.i + i * other.r;
+ r = tmp;
+ return *this;
+ }
+ template <typename T2>
+ cmplx &operator+=(const cmplx<T2> &other)
+ {
+ r += other.r;
+ i += other.i;
+ return *this;
+ }
+ template <typename T2>
+ cmplx &operator-=(const cmplx<T2> &other)
+ {
+ r -= other.r;
+ i -= other.i;
+ return *this;
+ }
+ template <typename T2>
+ auto operator*(const T2 &other) const -> cmplx<decltype(r *other)>
+ {
+ return {r * other, i * other};
+ }
+ template <typename T2>
+ auto operator+(const cmplx<T2> &other) const
+ -> cmplx<decltype(r + other.r)>
+ {
+ return {r + other.r, i + other.i};
+ }
+ template <typename T2>
+ auto operator-(const cmplx<T2> &other) const
+ -> cmplx<decltype(r + other.r)>
+ {
+ return {r - other.r, i - other.i};
+ }
+ template <typename T2>
+ auto operator*(const cmplx<T2> &other) const
+ -> cmplx<decltype(r + other.r)>
+ {
+ return {r * other.r - i * other.i, r * other.i + i * other.r};
+ }
+ template <bool fwd, typename T2>
+ auto special_mul(const cmplx<T2> &other) const
+ -> cmplx<decltype(r + other.r)>
+ {
+ using Tres = cmplx<decltype(r + other.r)>;
+ return fwd ? Tres(r * other.r + i * other.i, i * other.r - r * other.i)
+ : Tres(r * other.r - i * other.i, r * other.i + i * other.r);
+ }
+ };
+ template <typename T>
+ inline void PM(T &a, T &b, T c, T d)
+ {
+ a = c + d;
+ b = c - d;
+ }
+ template <typename T>
+ inline void PMINPLACE(T &a, T &b)
+ {
+ T t = a;
+ a += b;
+ b = t - b;
+ }
+ template <typename T>
+ inline void MPINPLACE(T &a, T &b)
+ {
+ T t = a;
+ a -= b;
+ b = t + b;
+ }
+ template <typename T>
+ cmplx<T> conj(const cmplx<T> &a)
+ {
+ return {a.r, -a.i};
+ }
+ template <bool fwd, typename T, typename T2>
+ void special_mul(const cmplx<T> &v1, const cmplx<T2> &v2, cmplx<T> &res)
+ {
+ res =
+ fwd ? cmplx<T>(v1.r * v2.r + v1.i * v2.i, v1.i * v2.r - v1.r * v2.i)
+ : cmplx<T>(v1.r * v2.r - v1.i * v2.i, v1.r * v2.i + v1.i * v2.r);
+ }
+
+ template <typename T>
+ void ROT90(cmplx<T> &a)
+ {
+ auto tmp_ = a.r;
+ a.r = -a.i;
+ a.i = tmp_;
+ }
+ template <bool fwd, typename T>
+ void ROTX90(cmplx<T> &a)
+ {
+ auto tmp_ = fwd ? -a.r : a.r;
+ a.r = fwd ? a.i : -a.i;
+ a.i = tmp_;
+ }
+
+ //
+ // twiddle factor section
+ //
+ template <typename T>
+ class sincos_2pibyn
+ {
+ private:
+ using Thigh = typename std::conditional<(sizeof(T) > sizeof(double)), T,
+ double>::type;
+ size_t N, mask, shift;
+ arr<cmplx<Thigh>> v1, v2;
+
+ static cmplx<Thigh> calc(size_t x, size_t n, Thigh ang)
+ {
+ x <<= 3;
+ if (x < 4 * n) // first half
+ {
+ if (x < 2 * n) // first quadrant
+ {
+ if (x < n)
+ return cmplx<Thigh>(std::cos(Thigh(x) * ang),
+ std::sin(Thigh(x) * ang));
+ return cmplx<Thigh>(std::sin(Thigh(2 * n - x) * ang),
+ std::cos(Thigh(2 * n - x) * ang));
+ } else // second quadrant
+ {
+ x -= 2 * n;
+ if (x < n)
+ return cmplx<Thigh>(-std::sin(Thigh(x) * ang),
+ std::cos(Thigh(x) * ang));
+ return cmplx<Thigh>(-std::cos(Thigh(2 * n - x) * ang),
+ std::sin(Thigh(2 * n - x) * ang));
+ }
+ } else {
+ x = 8 * n - x;
+ if (x < 2 * n) // third quadrant
+ {
+ if (x < n)
+ return cmplx<Thigh>(std::cos(Thigh(x) * ang),
+ -std::sin(Thigh(x) * ang));
+ return cmplx<Thigh>(std::sin(Thigh(2 * n - x) * ang),
+ -std::cos(Thigh(2 * n - x) * ang));
+ } else // fourth quadrant
+ {
+ x -= 2 * n;
+ if (x < n)
+ return cmplx<Thigh>(-std::sin(Thigh(x) * ang),
+ -std::cos(Thigh(x) * ang));
+ return cmplx<Thigh>(-std::cos(Thigh(2 * n - x) * ang),
+ -std::sin(Thigh(2 * n - x) * ang));
+ }
+ }
+ }
+
+ public:
+ POCKETFFT_NOINLINE sincos_2pibyn(size_t n) : N(n)
+ {
+ constexpr auto pi = 3.141592653589793238462643383279502884197L;
+ Thigh ang = Thigh(0.25L * pi / n);
+ size_t nval = (n + 2) / 2;
+ shift = 1;
+ while ((size_t(1) << shift) * (size_t(1) << shift) < nval)
+ ++shift;
+ mask = (size_t(1) << shift) - 1;
+ v1.resize(mask + 1);
+ v1[0].Set(Thigh(1), Thigh(0));
+ for (size_t i = 1; i < v1.size(); ++i)
+ v1[i] = calc(i, n, ang);
+ v2.resize((nval + mask) / (mask + 1));
+ v2[0].Set(Thigh(1), Thigh(0));
+ for (size_t i = 1; i < v2.size(); ++i)
+ v2[i] = calc(i * (mask + 1), n, ang);
+ }
+
+ cmplx<T> operator[](size_t idx) const
+ {
+ if (2 * idx <= N) {
+ auto x1 = v1[idx & mask], x2 = v2[idx >> shift];
+ return cmplx<T>(T(x1.r * x2.r - x1.i * x2.i),
+ T(x1.r * x2.i + x1.i * x2.r));
+ }
+ idx = N - idx;
+ auto x1 = v1[idx & mask], x2 = v2[idx >> shift];
+ return cmplx<T>(T(x1.r * x2.r - x1.i * x2.i),
+ -T(x1.r * x2.i + x1.i * x2.r));
+ }
+ };
+
+ struct util // hack to avoid duplicate symbols
+ {
+ static POCKETFFT_NOINLINE size_t largest_prime_factor(size_t n)
+ {
+ size_t res = 1;
+ while ((n & 1) == 0) {
+ res = 2;
+ n >>= 1;
+ }
+ for (size_t x = 3; x * x <= n; x += 2)
+ while ((n % x) == 0) {
+ res = x;
+ n /= x;
+ }
+ if (n > 1)
+ res = n;
+ return res;
+ }
+
+ static POCKETFFT_NOINLINE double cost_guess(size_t n)
+ {
+ constexpr double lfp = 1.1; // penalty for non-hardcoded larger factors
+ size_t ni = n;
+ double result = 0.;
+ while ((n & 1) == 0) {
+ result += 2;
+ n >>= 1;
+ }
+ for (size_t x = 3; x * x <= n; x += 2)
+ while ((n % x) == 0) {
+ result += (x <= 5)
+ ? double(x)
+ : lfp * double(x); // penalize larger prime factors
+ n /= x;
+ }
+ if (n > 1)
+ result += (n <= 5) ? double(n) : lfp * double(n);
+ return result * double(ni);
+ }
+
+ /* returns the smallest composite of 2, 3, 5, 7 and 11 which is >= n */
+ static POCKETFFT_NOINLINE size_t good_size_cmplx(size_t n)
+ {
+ if (n <= 12)
+ return n;
+
+ size_t bestfac = 2 * n;
+ for (size_t f11 = 1; f11 < bestfac; f11 *= 11)
+ for (size_t f117 = f11; f117 < bestfac; f117 *= 7)
+ for (size_t f1175 = f117; f1175 < bestfac; f1175 *= 5) {
+ size_t x = f1175;
+ while (x < n)
+ x *= 2;
+ for (;;) {
+ if (x < n)
+ x *= 3;
+ else if (x > n) {
+ if (x < bestfac)
+ bestfac = x;
+ if (x & 1)
+ break;
+ x >>= 1;
+ } else
+ return n;
+ }
+ }
+ return bestfac;
+ }
+
+ /* returns the smallest composite of 2, 3, 5 which is >= n */
+ static POCKETFFT_NOINLINE size_t good_size_real(size_t n)
+ {
+ if (n <= 6)
+ return n;
+
+ size_t bestfac = 2 * n;
+ for (size_t f5 = 1; f5 < bestfac; f5 *= 5) {
+ size_t x = f5;
+ while (x < n)
+ x *= 2;
+ for (;;) {
+ if (x < n)
+ x *= 3;
+ else if (x > n) {
+ if (x < bestfac)
+ bestfac = x;
+ if (x & 1)
+ break;
+ x >>= 1;
+ } else
+ return n;
+ }
+ }
+ return bestfac;
+ }
+
+ static size_t prod(const shape_t &shape)
+ {
+ size_t res = 1;
+ for (auto sz : shape)
+ res *= sz;
+ return res;
+ }
+
+ static POCKETFFT_NOINLINE void sanity_check(const shape_t &shape,
+ const stride_t &stride_in,
+ const stride_t &stride_out,
+ bool inplace)
+ {
+ auto ndim = shape.size();
+ if (ndim < 1)
+ throw std::runtime_error("ndim must be >= 1");
+ if ((stride_in.size() != ndim) || (stride_out.size() != ndim))
+ throw std::runtime_error("stride dimension mismatch");
+ if (inplace && (stride_in != stride_out))
+ throw std::runtime_error("stride mismatch");
+ }
+
+ static POCKETFFT_NOINLINE void sanity_check(const shape_t &shape,
+ const stride_t &stride_in,
+ const stride_t &stride_out,
+ bool inplace,
+ const shape_t &axes)
+ {
+ sanity_check(shape, stride_in, stride_out, inplace);
+ auto ndim = shape.size();
+ shape_t tmp(ndim, 0);
+ for (auto ax : axes) {
+ if (ax >= ndim)
+ throw std::invalid_argument("bad axis number");
+ if (++tmp[ax] > 1)
+ throw std::invalid_argument("axis specified repeatedly");
+ }
+ }
+
+ static POCKETFFT_NOINLINE void sanity_check(const shape_t &shape,
+ const stride_t &stride_in,
+ const stride_t &stride_out,
+ bool inplace, size_t axis)
+ {
+ sanity_check(shape, stride_in, stride_out, inplace);
+ if (axis >= shape.size())
+ throw std::invalid_argument("bad axis number");
+ }
+
+#ifdef POCKETFFT_NO_MULTITHREADING
+ static size_t thread_count(size_t /*nthreads*/, const shape_t & /*shape*/,
+ size_t /*axis*/, size_t /*vlen*/)
+ {
+ return 1;
+ }
+#else
+ static size_t thread_count(size_t nthreads, const shape_t &shape,
+ size_t axis, size_t vlen)
+ {
+ if (nthreads == 1)
+ return 1;
+ size_t size = prod(shape);
+ size_t parallel = size / (shape[axis] * vlen);
+ if (shape[axis] < 1000)
+ parallel /= 4;
+ size_t max_threads =
+ nthreads == 0 ? std::thread::hardware_concurrency() : nthreads;
+ return std::max(size_t(1), std::min(parallel, max_threads));
+ }
+#endif
+ };
+
+ namespace threading
+ {
+
+#ifdef POCKETFFT_NO_MULTITHREADING
+
+ constexpr inline size_t thread_id()
+ {
+ return 0;
+ }
+ constexpr inline size_t num_threads()
+ {
+ return 1;
+ }
+
+ template <typename Func>
+ void thread_map(size_t /* nthreads */, Func f)
+ {
+ f();
+ }
+
+#else
+
+ inline size_t &thread_id()
+ {
+ static thread_local size_t thread_id_ = 0;
+ return thread_id_;
+ }
+ inline size_t &num_threads()
+ {
+ static thread_local size_t num_threads_ = 1;
+ return num_threads_;
+ }
+ static const size_t max_threads =
+ std::max(1u, std::thread::hardware_concurrency());
+
+ class latch
+ {
+ std::atomic<size_t> num_left_;
+ std::mutex mut_;
+ std::condition_variable completed_;
+ using lock_t = std::unique_lock<std::mutex>;
+
+ public:
+ latch(size_t n) : num_left_(n)
+ {
+ }
+
+ void count_down()
+ {
+ lock_t lock(mut_);
+ if (--num_left_)
+ return;
+ completed_.notify_all();
+ }
+
+ void wait()
+ {
+ lock_t lock(mut_);
+ completed_.wait(lock, [this] { return is_ready(); });
+ }
+ bool is_ready()
+ {
+ return num_left_ == 0;
+ }
+ };
+
+ template <typename T>
+ class concurrent_queue
+ {
+ std::queue<T> q_;
+ std::mutex mut_;
+ std::condition_variable item_added_;
+ bool shutdown_;
+ using lock_t = std::unique_lock<std::mutex>;
+
+ public:
+ concurrent_queue() : shutdown_(false)
+ {
+ }
+
+ void push(T val)
+ {
+ {
+ lock_t lock(mut_);
+ if (shutdown_)
+ throw std::runtime_error("Item added to queue after shutdown");
+ q_.push(move(val));
+ }
+ item_added_.notify_one();
+ }
+
+ bool pop(T &val)
+ {
+ lock_t lock(mut_);
+ item_added_.wait(lock, [this] { return (!q_.empty() || shutdown_); });
+ if (q_.empty())
+ return false; // We are shutting down
+
+ val = std::move(q_.front());
+ q_.pop();
+ return true;
+ }
+
+ void shutdown()
+ {
+ {
+ lock_t lock(mut_);
+ shutdown_ = true;
+ }
+ item_added_.notify_all();
+ }
+
+ void restart()
+ {
+ shutdown_ = false;
+ }
+ };
+
+ class thread_pool
+ {
+ concurrent_queue<std::function<void()>> work_queue_;
+ std::vector<std::thread> threads_;
+
+ void worker_main()
+ {
+ std::function<void()> work;
+ while (work_queue_.pop(work))
+ work();
+ }
+
+ void create_threads()
+ {
+ size_t nthreads = threads_.size();
+ for (size_t i = 0; i < nthreads; ++i) {
+ try {
+ threads_[i] = std::thread([this] { worker_main(); });
+ } catch (...) {
+ shutdown();
+ throw;
+ }
+ }
+ }
+
+ public:
+ explicit thread_pool(size_t nthreads) : threads_(nthreads)
+ {
+ create_threads();
+ }
+
+ thread_pool() : thread_pool(max_threads)
+ {
+ }
+
+ ~thread_pool()
+ {
+ shutdown();
+ }
+
+ void submit(std::function<void()> work)
+ {
+ work_queue_.push(move(work));
+ }
+
+ void shutdown()
+ {
+ work_queue_.shutdown();
+ for (auto &thread : threads_)
+ if (thread.joinable())
+ thread.join();
+ }
+
+ void restart()
+ {
+ work_queue_.restart();
+ create_threads();
+ }
+ };
+
+ inline thread_pool &get_pool()
+ {
+ static thread_pool pool;
+#ifdef POCKETFFT_PTHREADS
+ static std::once_flag f;
+ std::call_once(f, [] {
+ pthread_atfork(+[] { get_pool().shutdown(); }, // prepare
+ +[] { get_pool().restart(); }, // parent
+ +[] { get_pool().restart(); } // child
+ );
+ });
+#endif
+
+ return pool;
+ }
+
+ /** Map a function f over nthreads */
+ template <typename Func>
+ void thread_map(size_t nthreads, Func f)
+ {
+ if (nthreads == 0)
+ nthreads = max_threads;
+
+ if (nthreads == 1) {
+ f();
+ return;
+ }
+
+ auto &pool = get_pool();
+ latch counter(nthreads);
+ std::exception_ptr ex;
+ std::mutex ex_mut;
+ for (size_t i = 0; i < nthreads; ++i) {
+ pool.submit([&f, &counter, &ex, &ex_mut, i, nthreads] {
+ thread_id() = i;
+ num_threads() = nthreads;
+ try {
+ f();
+ } catch (...) {
+ std::lock_guard<std::mutex> lock(ex_mut);
+ ex = std::current_exception();
+ }
+ counter.count_down();
+ });
+ }
+ counter.wait();
+ if (ex)
+ std::rethrow_exception(ex);
+ }
+
+#endif
+ }
+
+ //
+ // complex FFTPACK transforms
+ //
+
+ template <typename T0>
+ class cfftp
+ {
+ private:
+ struct fctdata {
+ size_t fct;
+ cmplx<T0> *tw, *tws;
+ };
+
+ size_t length;
+ arr<cmplx<T0>> mem;
+ std::vector<fctdata> fact;
+
+ void add_factor(size_t factor)
+ {
+ fact.push_back({factor, nullptr, nullptr});
+ }
+
+ template <bool fwd, typename T>
+ void pass2(size_t ido, size_t l1, const T *POCKETFFT_RESTRICT cc,
+ T *POCKETFFT_RESTRICT ch,
+ const cmplx<T0> *POCKETFFT_RESTRICT wa) const
+ {
+ auto CH = [ch, ido, l1](size_t a, size_t b, size_t c)
+ -> T &{ return ch[a + ido * (b + l1 * c)]; };
+ auto CC = [cc, ido](size_t a, size_t b, size_t c)
+ -> const T &{ return cc[a + ido * (b + 2 * c)]; };
+ auto WA =
+ [wa, ido](size_t x, size_t i) { return wa[i - 1 + x * (ido - 1)]; };
+
+ if (ido == 1)
+ for (size_t k = 0; k < l1; ++k) {
+ CH(0, k, 0) = CC(0, 0, k) + CC(0, 1, k);
+ CH(0, k, 1) = CC(0, 0, k) - CC(0, 1, k);
+ }
+ else
+ for (size_t k = 0; k < l1; ++k) {
+ CH(0, k, 0) = CC(0, 0, k) + CC(0, 1, k);
+ CH(0, k, 1) = CC(0, 0, k) - CC(0, 1, k);
+ for (size_t i = 1; i < ido; ++i) {
+ CH(i, k, 0) = CC(i, 0, k) + CC(i, 1, k);
+ special_mul<fwd>(CC(i, 0, k) - CC(i, 1, k), WA(0, i),
+ CH(i, k, 1));
+ }
+ }
+ }
+
+#define POCKETFFT_PREP3(idx) \
+ T t0 = CC(idx, 0, k), t1, t2; \
+ PM(t1, t2, CC(idx, 1, k), CC(idx, 2, k)); \
+ CH(idx, k, 0) = t0 + t1;
+#define POCKETFFT_PARTSTEP3a(u1, u2, twr, twi) \
+ { \
+ T ca = t0 + t1 * twr; \
+ T cb{-t2.i * twi, t2.r * twi}; \
+ PM(CH(0, k, u1), CH(0, k, u2), ca, cb); \
+ }
+#define POCKETFFT_PARTSTEP3b(u1, u2, twr, twi) \
+ { \
+ T ca = t0 + t1 * twr; \
+ T cb{-t2.i * twi, t2.r * twi}; \
+ special_mul<fwd>(ca + cb, WA(u1 - 1, i), CH(i, k, u1)); \
+ special_mul<fwd>(ca - cb, WA(u2 - 1, i), CH(i, k, u2)); \
+ }
+ template <bool fwd, typename T>
+ void pass3(size_t ido, size_t l1, const T *POCKETFFT_RESTRICT cc,
+ T *POCKETFFT_RESTRICT ch,
+ const cmplx<T0> *POCKETFFT_RESTRICT wa) const
+ {
+ constexpr T0 tw1r = -0.5,
+ tw1i = (fwd ? -1 : 1) *
+ T0(0.8660254037844386467637231707529362L);
+
+ auto CH = [ch, ido, l1](size_t a, size_t b, size_t c)
+ -> T &{ return ch[a + ido * (b + l1 * c)]; };
+ auto CC = [cc, ido](size_t a, size_t b, size_t c)
+ -> const T &{ return cc[a + ido * (b + 3 * c)]; };
+ auto WA =
+ [wa, ido](size_t x, size_t i) { return wa[i - 1 + x * (ido - 1)]; };
+
+ if (ido == 1)
+ for (size_t k = 0; k < l1; ++k) {
+ POCKETFFT_PREP3(0)
+ POCKETFFT_PARTSTEP3a(1, 2, tw1r, tw1i)
+ }
+ else
+ for (size_t k = 0; k < l1; ++k) {
+ {
+ POCKETFFT_PREP3(0)
+ POCKETFFT_PARTSTEP3a(1, 2, tw1r, tw1i)
+ }
+ for (size_t i = 1; i < ido; ++i) {
+ POCKETFFT_PREP3(i)
+ POCKETFFT_PARTSTEP3b(1, 2, tw1r, tw1i)
+ }
+ }
+ }
+
+#undef POCKETFFT_PARTSTEP3b
+#undef POCKETFFT_PARTSTEP3a
+#undef POCKETFFT_PREP3
+
+ template <bool fwd, typename T>
+ void pass4(size_t ido, size_t l1, const T *POCKETFFT_RESTRICT cc,
+ T *POCKETFFT_RESTRICT ch,
+ const cmplx<T0> *POCKETFFT_RESTRICT wa) const
+ {
+ auto CH = [ch, ido, l1](size_t a, size_t b, size_t c)
+ -> T &{ return ch[a + ido * (b + l1 * c)]; };
+ auto CC = [cc, ido](size_t a, size_t b, size_t c)
+ -> const T &{ return cc[a + ido * (b + 4 * c)]; };
+ auto WA =
+ [wa, ido](size_t x, size_t i) { return wa[i - 1 + x * (ido - 1)]; };
+
+ if (ido == 1)
+ for (size_t k = 0; k < l1; ++k) {
+ T t1, t2, t3, t4;
+ PM(t2, t1, CC(0, 0, k), CC(0, 2, k));
+ PM(t3, t4, CC(0, 1, k), CC(0, 3, k));
+ ROTX90<fwd>(t4);
+ PM(CH(0, k, 0), CH(0, k, 2), t2, t3);
+ PM(CH(0, k, 1), CH(0, k, 3), t1, t4);
+ }
+ else
+ for (size_t k = 0; k < l1; ++k) {
+ {
+ T t1, t2, t3, t4;
+ PM(t2, t1, CC(0, 0, k), CC(0, 2, k));
+ PM(t3, t4, CC(0, 1, k), CC(0, 3, k));
+ ROTX90<fwd>(t4);
+ PM(CH(0, k, 0), CH(0, k, 2), t2, t3);
+ PM(CH(0, k, 1), CH(0, k, 3), t1, t4);
+ }
+ for (size_t i = 1; i < ido; ++i) {
+ T t1, t2, t3, t4;
+ T cc0 = CC(i, 0, k), cc1 = CC(i, 1, k), cc2 = CC(i, 2, k),
+ cc3 = CC(i, 3, k);
+ PM(t2, t1, cc0, cc2);
+ PM(t3, t4, cc1, cc3);
+ ROTX90<fwd>(t4);
+ CH(i, k, 0) = t2 + t3;
+ special_mul<fwd>(t1 + t4, WA(0, i), CH(i, k, 1));
+ special_mul<fwd>(t2 - t3, WA(1, i), CH(i, k, 2));
+ special_mul<fwd>(t1 - t4, WA(2, i), CH(i, k, 3));
+ }
+ }
+ }
+
+#define POCKETFFT_PREP5(idx) \
+ T t0 = CC(idx, 0, k), t1, t2, t3, t4; \
+ PM(t1, t4, CC(idx, 1, k), CC(idx, 4, k)); \
+ PM(t2, t3, CC(idx, 2, k), CC(idx, 3, k)); \
+ CH(idx, k, 0).r = t0.r + t1.r + t2.r; \
+ CH(idx, k, 0).i = t0.i + t1.i + t2.i;
+
+#define POCKETFFT_PARTSTEP5a(u1, u2, twar, twbr, twai, twbi) \
+ { \
+ T ca, cb; \
+ ca.r = t0.r + twar * t1.r + twbr * t2.r; \
+ ca.i = t0.i + twar * t1.i + twbr * t2.i; \
+ cb.i = twai * t4.r twbi * t3.r; \
+ cb.r = -(twai * t4.i twbi * t3.i); \
+ PM(CH(0, k, u1), CH(0, k, u2), ca, cb); \
+ }
+
+#define POCKETFFT_PARTSTEP5b(u1, u2, twar, twbr, twai, twbi) \
+ { \
+ T ca, cb, da, db; \
+ ca.r = t0.r + twar * t1.r + twbr * t2.r; \
+ ca.i = t0.i + twar * t1.i + twbr * t2.i; \
+ cb.i = twai * t4.r twbi * t3.r; \
+ cb.r = -(twai * t4.i twbi * t3.i); \
+ special_mul<fwd>(ca + cb, WA(u1 - 1, i), CH(i, k, u1)); \
+ special_mul<fwd>(ca - cb, WA(u2 - 1, i), CH(i, k, u2)); \
+ }
+ template <bool fwd, typename T>
+ void pass5(size_t ido, size_t l1, const T *POCKETFFT_RESTRICT cc,
+ T *POCKETFFT_RESTRICT ch,
+ const cmplx<T0> *POCKETFFT_RESTRICT wa) const
+ {
+ constexpr T0 tw1r = T0(0.3090169943749474241022934171828191L),
+ tw1i = (fwd ? -1 : 1) *
+ T0(0.9510565162951535721164393333793821L),
+ tw2r = T0(-0.8090169943749474241022934171828191L),
+ tw2i = (fwd ? -1 : 1) *
+ T0(0.5877852522924731291687059546390728L);
+
+ auto CH = [ch, ido, l1](size_t a, size_t b, size_t c)
+ -> T &{ return ch[a + ido * (b + l1 * c)]; };
+ auto CC = [cc, ido](size_t a, size_t b, size_t c)
+ -> const T &{ return cc[a + ido * (b + 5 * c)]; };
+ auto WA =
+ [wa, ido](size_t x, size_t i) { return wa[i - 1 + x * (ido - 1)]; };
+
+ if (ido == 1)
+ for (size_t k = 0; k < l1; ++k) {
+ POCKETFFT_PREP5(0)
+ POCKETFFT_PARTSTEP5a(1, 4, tw1r, tw2r, +tw1i, +tw2i)
+ POCKETFFT_PARTSTEP5a(2, 3, tw2r, tw1r, +tw2i, -tw1i)
+ }
+ else
+ for (size_t k = 0; k < l1; ++k) {
+ {
+ POCKETFFT_PREP5(0)
+ POCKETFFT_PARTSTEP5a(1, 4, tw1r, tw2r, +tw1i, +tw2i)
+ POCKETFFT_PARTSTEP5a(2, 3, tw2r, tw1r, +tw2i, -tw1i)
+ }
+ for (size_t i = 1; i < ido; ++i) {
+ POCKETFFT_PREP5(i)
+ POCKETFFT_PARTSTEP5b(1, 4, tw1r, tw2r, +tw1i, +tw2i)
+ POCKETFFT_PARTSTEP5b(2, 3, tw2r, tw1r, +tw2i, -tw1i)
+ }
+ }
+ }
+
+#undef POCKETFFT_PARTSTEP5b
+#undef POCKETFFT_PARTSTEP5a
+#undef POCKETFFT_PREP5
+
+#define POCKETFFT_PREP7(idx) \
+ T t1 = CC(idx, 0, k), t2, t3, t4, t5, t6, t7; \
+ PM(t2, t7, CC(idx, 1, k), CC(idx, 6, k)); \
+ PM(t3, t6, CC(idx, 2, k), CC(idx, 5, k)); \
+ PM(t4, t5, CC(idx, 3, k), CC(idx, 4, k)); \
+ CH(idx, k, 0).r = t1.r + t2.r + t3.r + t4.r; \
+ CH(idx, k, 0).i = t1.i + t2.i + t3.i + t4.i;
+
+#define POCKETFFT_PARTSTEP7a0(u1, u2, x1, x2, x3, y1, y2, y3, out1, out2) \
+ { \
+ T ca, cb; \
+ ca.r = t1.r + x1 * t2.r + x2 * t3.r + x3 * t4.r; \
+ ca.i = t1.i + x1 * t2.i + x2 * t3.i + x3 * t4.i; \
+ cb.i = y1 * t7.r y2 * t6.r y3 * t5.r; \
+ cb.r = -(y1 * t7.i y2 * t6.i y3 * t5.i); \
+ PM(out1, out2, ca, cb); \
+ }
+#define POCKETFFT_PARTSTEP7a(u1, u2, x1, x2, x3, y1, y2, y3) \
+ POCKETFFT_PARTSTEP7a0(u1, u2, x1, x2, x3, y1, y2, y3, CH(0, k, u1), \
+ CH(0, k, u2))
+#define POCKETFFT_PARTSTEP7(u1, u2, x1, x2, x3, y1, y2, y3) \
+ { \
+ T da, db; \
+ POCKETFFT_PARTSTEP7a0(u1, u2, x1, x2, x3, y1, y2, y3, da, db) \
+ special_mul<fwd>(da, WA(u1 - 1, i), CH(i, k, u1)); \
+ special_mul<fwd>(db, WA(u2 - 1, i), CH(i, k, u2)); \
+ }
+
+ template <bool fwd, typename T>
+ void pass7(size_t ido, size_t l1, const T *POCKETFFT_RESTRICT cc,
+ T *POCKETFFT_RESTRICT ch,
+ const cmplx<T0> *POCKETFFT_RESTRICT wa) const
+ {
+ constexpr T0 tw1r = T0(0.6234898018587335305250048840042398L),
+ tw1i = (fwd ? -1 : 1) *
+ T0(0.7818314824680298087084445266740578L),
+ tw2r = T0(-0.2225209339563144042889025644967948L),
+ tw2i = (fwd ? -1 : 1) *
+ T0(0.9749279121818236070181316829939312L),
+ tw3r = T0(-0.9009688679024191262361023195074451L),
+ tw3i = (fwd ? -1 : 1) *
+ T0(0.433883739117558120475768332848359L);
+
+ auto CH = [ch, ido, l1](size_t a, size_t b, size_t c)
+ -> T &{ return ch[a + ido * (b + l1 * c)]; };
+ auto CC = [cc, ido](size_t a, size_t b, size_t c)
+ -> const T &{ return cc[a + ido * (b + 7 * c)]; };
+ auto WA =
+ [wa, ido](size_t x, size_t i) { return wa[i - 1 + x * (ido - 1)]; };
+
+ if (ido == 1)
+ for (size_t k = 0; k < l1; ++k) {
+ POCKETFFT_PREP7(0)
+ POCKETFFT_PARTSTEP7a(1, 6, tw1r, tw2r, tw3r, +tw1i, +tw2i, +tw3i)
+ POCKETFFT_PARTSTEP7a(2, 5, tw2r, tw3r, tw1r, +tw2i, -tw3i,
+ -tw1i)
+ POCKETFFT_PARTSTEP7a(3, 4, tw3r, tw1r, tw2r, +tw3i, -tw1i,
+ +tw2i)
+ }
+ else
+ for (size_t k = 0; k < l1; ++k) {
+ {
+ POCKETFFT_PREP7(0)
+ POCKETFFT_PARTSTEP7a(1, 6, tw1r, tw2r, tw3r, +tw1i, +tw2i, +tw3i)
+ POCKETFFT_PARTSTEP7a(2, 5, tw2r, tw3r, tw1r, +tw2i, -tw3i,
+ -tw1i)
+ POCKETFFT_PARTSTEP7a(3, 4, tw3r, tw1r, tw2r, +tw3i, -tw1i,
+ +tw2i)
+ }
+ for (size_t i = 1; i < ido; ++i) {
+ POCKETFFT_PREP7(i)
+ POCKETFFT_PARTSTEP7(1, 6, tw1r, tw2r, tw3r, +tw1i, +tw2i, +tw3i)
+ POCKETFFT_PARTSTEP7(2, 5, tw2r, tw3r, tw1r, +tw2i, -tw3i, -tw1i)
+ POCKETFFT_PARTSTEP7(3, 4, tw3r, tw1r, tw2r, +tw3i, -tw1i, +tw2i)
+ }
+ }
+ }
+
+#undef POCKETFFT_PARTSTEP7
+#undef POCKETFFT_PARTSTEP7a0
+#undef POCKETFFT_PARTSTEP7a
+#undef POCKETFFT_PREP7
+
+ template <bool fwd, typename T>
+ void ROTX45(T &a) const
+ {
+ constexpr T0 hsqt2 = T0(0.707106781186547524400844362104849L);
+ if (fwd) {
+ auto tmp_ = a.r;
+ a.r = hsqt2 * (a.r + a.i);
+ a.i = hsqt2 * (a.i - tmp_);
+ } else {
+ auto tmp_ = a.r;
+ a.r = hsqt2 * (a.r - a.i);
+ a.i = hsqt2 * (a.i + tmp_);
+ }
+ }
+ template <bool fwd, typename T>
+ void ROTX135(T &a) const
+ {
+ constexpr T0 hsqt2 = T0(0.707106781186547524400844362104849L);
+ if (fwd) {
+ auto tmp_ = a.r;
+ a.r = hsqt2 * (a.i - a.r);
+ a.i = hsqt2 * (-tmp_ - a.i);
+ } else {
+ auto tmp_ = a.r;
+ a.r = hsqt2 * (-a.r - a.i);
+ a.i = hsqt2 * (tmp_ - a.i);
+ }
+ }
+
+ template <bool fwd, typename T>
+ void pass8(size_t ido, size_t l1, const T *POCKETFFT_RESTRICT cc,
+ T *POCKETFFT_RESTRICT ch,
+ const cmplx<T0> *POCKETFFT_RESTRICT wa) const
+ {
+ auto CH = [ch, ido, l1](size_t a, size_t b, size_t c)
+ -> T &{ return ch[a + ido * (b + l1 * c)]; };
+ auto CC = [cc, ido](size_t a, size_t b, size_t c)
+ -> const T &{ return cc[a + ido * (b + 8 * c)]; };
+ auto WA =
+ [wa, ido](size_t x, size_t i) { return wa[i - 1 + x * (ido - 1)]; };
+
+ if (ido == 1)
+ for (size_t k = 0; k < l1; ++k) {
+ T a0, a1, a2, a3, a4, a5, a6, a7;
+ PM(a1, a5, CC(0, 1, k), CC(0, 5, k));
+ PM(a3, a7, CC(0, 3, k), CC(0, 7, k));
+ PMINPLACE(a1, a3);
+ ROTX90<fwd>(a3);
+
+ ROTX90<fwd>(a7);
+ PMINPLACE(a5, a7);
+ ROTX45<fwd>(a5);
+ ROTX135<fwd>(a7);
+
+ PM(a0, a4, CC(0, 0, k), CC(0, 4, k));
+ PM(a2, a6, CC(0, 2, k), CC(0, 6, k));
+ PM(CH(0, k, 0), CH(0, k, 4), a0 + a2, a1);
+ PM(CH(0, k, 2), CH(0, k, 6), a0 - a2, a3);
+ ROTX90<fwd>(a6);
+ PM(CH(0, k, 1), CH(0, k, 5), a4 + a6, a5);
+ PM(CH(0, k, 3), CH(0, k, 7), a4 - a6, a7);
+ }
+ else
+ for (size_t k = 0; k < l1; ++k) {
+ {
+ T a0, a1, a2, a3, a4, a5, a6, a7;
+ PM(a1, a5, CC(0, 1, k), CC(0, 5, k));
+ PM(a3, a7, CC(0, 3, k), CC(0, 7, k));
+ PMINPLACE(a1, a3);
+ ROTX90<fwd>(a3);
+
+ ROTX90<fwd>(a7);
+ PMINPLACE(a5, a7);
+ ROTX45<fwd>(a5);
+ ROTX135<fwd>(a7);
+
+ PM(a0, a4, CC(0, 0, k), CC(0, 4, k));
+ PM(a2, a6, CC(0, 2, k), CC(0, 6, k));
+ PM(CH(0, k, 0), CH(0, k, 4), a0 + a2, a1);
+ PM(CH(0, k, 2), CH(0, k, 6), a0 - a2, a3);
+ ROTX90<fwd>(a6);
+ PM(CH(0, k, 1), CH(0, k, 5), a4 + a6, a5);
+ PM(CH(0, k, 3), CH(0, k, 7), a4 - a6, a7);
+ }
+ for (size_t i = 1; i < ido; ++i) {
+ T a0, a1, a2, a3, a4, a5, a6, a7;
+ PM(a1, a5, CC(i, 1, k), CC(i, 5, k));
+ PM(a3, a7, CC(i, 3, k), CC(i, 7, k));
+ ROTX90<fwd>(a7);
+ PMINPLACE(a1, a3);
+ ROTX90<fwd>(a3);
+ PMINPLACE(a5, a7);
+ ROTX45<fwd>(a5);
+ ROTX135<fwd>(a7);
+ PM(a0, a4, CC(i, 0, k), CC(i, 4, k));
+ PM(a2, a6, CC(i, 2, k), CC(i, 6, k));
+ PMINPLACE(a0, a2);
+ CH(i, k, 0) = a0 + a1;
+ special_mul<fwd>(a0 - a1, WA(3, i), CH(i, k, 4));
+ special_mul<fwd>(a2 + a3, WA(1, i), CH(i, k, 2));
+ special_mul<fwd>(a2 - a3, WA(5, i), CH(i, k, 6));
+ ROTX90<fwd>(a6);
+ PMINPLACE(a4, a6);
+ special_mul<fwd>(a4 + a5, WA(0, i), CH(i, k, 1));
+ special_mul<fwd>(a4 - a5, WA(4, i), CH(i, k, 5));
+ special_mul<fwd>(a6 + a7, WA(2, i), CH(i, k, 3));
+ special_mul<fwd>(a6 - a7, WA(6, i), CH(i, k, 7));
+ }
+ }
+ }
+
+#define POCKETFFT_PREP11(idx) \
+ T t1 = CC(idx, 0, k), t2, t3, t4, t5, t6, t7, t8, t9, t10, t11; \
+ PM(t2, t11, CC(idx, 1, k), CC(idx, 10, k)); \
+ PM(t3, t10, CC(idx, 2, k), CC(idx, 9, k)); \
+ PM(t4, t9, CC(idx, 3, k), CC(idx, 8, k)); \
+ PM(t5, t8, CC(idx, 4, k), CC(idx, 7, k)); \
+ PM(t6, t7, CC(idx, 5, k), CC(idx, 6, k)); \
+ CH(idx, k, 0).r = t1.r + t2.r + t3.r + t4.r + t5.r + t6.r; \
+ CH(idx, k, 0).i = t1.i + t2.i + t3.i + t4.i + t5.i + t6.i;
+
+#define POCKETFFT_PARTSTEP11a0(u1, u2, x1, x2, x3, x4, x5, y1, y2, y3, y4, y5, \
+ out1, out2) \
+ { \
+ T ca = t1 + t2 * x1 + t3 * x2 + t4 * x3 + t5 * x4 + t6 * x5, cb; \
+ cb.i = y1 * t11.r y2 * t10.r y3 * t9.r y4 * t8.r y5 * t7.r; \
+ cb.r = -(y1 * t11.i y2 * t10.i y3 * t9.i y4 * t8.i y5 * t7.i); \
+ PM(out1, out2, ca, cb); \
+ }
+#define POCKETFFT_PARTSTEP11a(u1, u2, x1, x2, x3, x4, x5, y1, y2, y3, y4, y5) \
+ POCKETFFT_PARTSTEP11a0(u1, u2, x1, x2, x3, x4, x5, y1, y2, y3, y4, y5, \
+ CH(0, k, u1), CH(0, k, u2))
+#define POCKETFFT_PARTSTEP11(u1, u2, x1, x2, x3, x4, x5, y1, y2, y3, y4, y5) \
+ { \
+ T da, db; \
+ POCKETFFT_PARTSTEP11a0(u1, u2, x1, x2, x3, x4, x5, y1, y2, y3, y4, y5, da, \
+ db) \
+ special_mul<fwd>(da, WA(u1 - 1, i), CH(i, k, u1)); \
+ special_mul<fwd>(db, WA(u2 - 1, i), CH(i, k, u2)); \
+ }
+
+ template <bool fwd, typename T>
+ void pass11(size_t ido, size_t l1, const T *POCKETFFT_RESTRICT cc,
+ T *POCKETFFT_RESTRICT ch,
+ const cmplx<T0> *POCKETFFT_RESTRICT wa) const
+ {
+ constexpr T0
+ tw1r = T0(0.8412535328311811688618116489193677L),
+ tw1i = (fwd ? -1 : 1) * T0(0.5406408174555975821076359543186917L),
+ tw2r = T0(0.4154150130018864255292741492296232L),
+ tw2i = (fwd ? -1 : 1) * T0(0.9096319953545183714117153830790285L),
+ tw3r = T0(-0.1423148382732851404437926686163697L),
+ tw3i = (fwd ? -1 : 1) * T0(0.9898214418809327323760920377767188L),
+ tw4r = T0(-0.6548607339452850640569250724662936L),
+ tw4i = (fwd ? -1 : 1) * T0(0.7557495743542582837740358439723444L),
+ tw5r = T0(-0.9594929736144973898903680570663277L),
+ tw5i = (fwd ? -1 : 1) * T0(0.2817325568414296977114179153466169L);
+
+ auto CH = [ch, ido, l1](size_t a, size_t b, size_t c)
+ -> T &{ return ch[a + ido * (b + l1 * c)]; };
+ auto CC = [cc, ido](size_t a, size_t b, size_t c)
+ -> const T &{ return cc[a + ido * (b + 11 * c)]; };
+ auto WA =
+ [wa, ido](size_t x, size_t i) { return wa[i - 1 + x * (ido - 1)]; };
+
+ if (ido == 1)
+ for (size_t k = 0; k < l1; ++k) {
+ POCKETFFT_PREP11(0)
+ POCKETFFT_PARTSTEP11a(1, 10, tw1r, tw2r, tw3r, tw4r, tw5r, +tw1i,
+ +tw2i, +tw3i, +tw4i, +tw5i)
+ POCKETFFT_PARTSTEP11a(2, 9, tw2r, tw4r, tw5r, tw3r, tw1r, +tw2i,
+ +tw4i, -tw5i, -tw3i, -tw1i)
+ POCKETFFT_PARTSTEP11a(3, 8, tw3r, tw5r, tw2r, tw1r, tw4r,
+ +tw3i, -tw5i, -tw2i, +tw1i, +tw4i)
+ POCKETFFT_PARTSTEP11a(4, 7, tw4r, tw3r, tw1r, tw5r,
+ tw2r, +tw4i, -tw3i, +tw1i, +tw5i,
+ -tw2i)
+ POCKETFFT_PARTSTEP11a(5, 6, tw5r, tw1r, tw4r, tw2r,
+ tw3r, +tw5i, -tw1i, +tw4i,
+ -tw2i, +tw3i)
+ }
+ else
+ for (size_t k = 0; k < l1; ++k) {
+ {
+ POCKETFFT_PREP11(0)
+ POCKETFFT_PARTSTEP11a(1, 10, tw1r, tw2r, tw3r, tw4r, tw5r, +tw1i,
+ +tw2i, +tw3i, +tw4i, +tw5i)
+ POCKETFFT_PARTSTEP11a(2, 9, tw2r, tw4r, tw5r, tw3r, tw1r,
+ +tw2i, +tw4i, -tw5i, -tw3i, -tw1i)
+ POCKETFFT_PARTSTEP11a(3, 8, tw3r, tw5r, tw2r, tw1r, tw4r,
+ +tw3i, -tw5i, -tw2i, +tw1i, +tw4i)
+ POCKETFFT_PARTSTEP11a(4, 7, tw4r, tw3r, tw1r, tw5r,
+ tw2r, +tw4i, -tw3i, +tw1i,
+ +tw5i, -tw2i)
+ POCKETFFT_PARTSTEP11a(5, 6, tw5r, tw1r, tw4r,
+ tw2r, tw3r, +tw5i, -tw1i,
+ +tw4i, -tw2i, +tw3i)
+ }
+ for (size_t i = 1; i < ido; ++i) {
+ POCKETFFT_PREP11(i)
+ POCKETFFT_PARTSTEP11(1, 10, tw1r, tw2r, tw3r, tw4r, tw5r, +tw1i,
+ +tw2i, +tw3i, +tw4i, +tw5i)
+ POCKETFFT_PARTSTEP11(2, 9, tw2r, tw4r, tw5r, tw3r, tw1r, +tw2i,
+ +tw4i, -tw5i, -tw3i, -tw1i)
+ POCKETFFT_PARTSTEP11(3, 8, tw3r, tw5r, tw2r, tw1r, tw4r, +tw3i,
+ -tw5i, -tw2i, +tw1i, +tw4i)
+ POCKETFFT_PARTSTEP11(4, 7, tw4r, tw3r, tw1r, tw5r, tw2r, +tw4i,
+ -tw3i, +tw1i, +tw5i, -tw2i)
+ POCKETFFT_PARTSTEP11(5, 6, tw5r, tw1r, tw4r, tw2r, tw3r, +tw5i,
+ -tw1i, +tw4i, -tw2i, +tw3i)
+ }
+ }
+ }
+
+#undef PARTSTEP11
+#undef PARTSTEP11a0
+#undef PARTSTEP11a
+#undef POCKETFFT_PREP11
+
+ template <bool fwd, typename T>
+ void passg(size_t ido, size_t ip, size_t l1, T *POCKETFFT_RESTRICT cc,
+ T *POCKETFFT_RESTRICT ch,
+ const cmplx<T0> *POCKETFFT_RESTRICT wa,
+ const cmplx<T0> *POCKETFFT_RESTRICT csarr) const
+ {
+ const size_t cdim = ip;
+ size_t ipph = (ip + 1) / 2;
+ size_t idl1 = ido * l1;
+
+ auto CH = [ch, ido, l1](size_t a, size_t b, size_t c)
+ -> T &{ return ch[a + ido * (b + l1 * c)]; };
+ auto CC = [cc, ido, cdim](size_t a, size_t b, size_t c)
+ -> const T &{ return cc[a + ido * (b + cdim * c)]; };
+ auto CX = [cc, ido, l1](size_t a, size_t b, size_t c)
+ -> T &{ return cc[a + ido * (b + l1 * c)]; };
+ auto CX2 =
+ [cc, idl1](size_t a, size_t b) -> T &{ return cc[a + idl1 * b]; };
+ auto CH2 = [ch, idl1](size_t a, size_t b)
+ -> const T &{ return ch[a + idl1 * b]; };
+
+ arr<cmplx<T0>> wal(ip);
+ wal[0] = cmplx<T0>(1., 0.);
+ for (size_t i = 1; i < ip; ++i)
+ wal[i] = cmplx<T0>(csarr[i].r, fwd ? -csarr[i].i : csarr[i].i);
+
+ for (size_t k = 0; k < l1; ++k)
+ for (size_t i = 0; i < ido; ++i)
+ CH(i, k, 0) = CC(i, 0, k);
+ for (size_t j = 1, jc = ip - 1; j < ipph; ++j, --jc)
+ for (size_t k = 0; k < l1; ++k)
+ for (size_t i = 0; i < ido; ++i)
+ PM(CH(i, k, j), CH(i, k, jc), CC(i, j, k), CC(i, jc, k));
+ for (size_t k = 0; k < l1; ++k)
+ for (size_t i = 0; i < ido; ++i) {
+ T tmp = CH(i, k, 0);
+ for (size_t j = 1; j < ipph; ++j)
+ tmp += CH(i, k, j);
+ CX(i, k, 0) = tmp;
+ }
+ for (size_t l = 1, lc = ip - 1; l < ipph; ++l, --lc) {
+ // j=0
+ for (size_t ik = 0; ik < idl1; ++ik) {
+ CX2(ik, l).r = CH2(ik, 0).r + wal[l].r * CH2(ik, 1).r +
+ wal[2 * l].r * CH2(ik, 2).r;
+ CX2(ik, l).i = CH2(ik, 0).i + wal[l].r * CH2(ik, 1).i +
+ wal[2 * l].r * CH2(ik, 2).i;
+ CX2(ik, lc).r = -wal[l].i * CH2(ik, ip - 1).i -
+ wal[2 * l].i * CH2(ik, ip - 2).i;
+ CX2(ik, lc).i =
+ wal[l].i * CH2(ik, ip - 1).r + wal[2 * l].i * CH2(ik, ip - 2).r;
+ }
+
+ size_t iwal = 2 * l;
+ size_t j = 3, jc = ip - 3;
+ for (; j < ipph - 1; j += 2, jc -= 2) {
+ iwal += l;
+ if (iwal > ip)
+ iwal -= ip;
+ cmplx<T0> xwal = wal[iwal];
+ iwal += l;
+ if (iwal > ip)
+ iwal -= ip;
+ cmplx<T0> xwal2 = wal[iwal];
+ for (size_t ik = 0; ik < idl1; ++ik) {
+ CX2(ik, l).r +=
+ CH2(ik, j).r * xwal.r + CH2(ik, j + 1).r * xwal2.r;
+ CX2(ik, l).i +=
+ CH2(ik, j).i * xwal.r + CH2(ik, j + 1).i * xwal2.r;
+ CX2(ik, lc).r -=
+ CH2(ik, jc).i * xwal.i + CH2(ik, jc - 1).i * xwal2.i;
+ CX2(ik, lc).i +=
+ CH2(ik, jc).r * xwal.i + CH2(ik, jc - 1).r * xwal2.i;
+ }
+ }
+ for (; j < ipph; ++j, --jc) {
+ iwal += l;
+ if (iwal > ip)
+ iwal -= ip;
+ cmplx<T0> xwal = wal[iwal];
+ for (size_t ik = 0; ik < idl1; ++ik) {
+ CX2(ik, l).r += CH2(ik, j).r * xwal.r;
+ CX2(ik, l).i += CH2(ik, j).i * xwal.r;
+ CX2(ik, lc).r -= CH2(ik, jc).i * xwal.i;
+ CX2(ik, lc).i += CH2(ik, jc).r * xwal.i;
+ }
+ }
+ }
+
+ // shuffling and twiddling
+ if (ido == 1)
+ for (size_t j = 1, jc = ip - 1; j < ipph; ++j, --jc)
+ for (size_t ik = 0; ik < idl1; ++ik) {
+ T t1 = CX2(ik, j), t2 = CX2(ik, jc);
+ PM(CX2(ik, j), CX2(ik, jc), t1, t2);
+ }
+ else {
+ for (size_t j = 1, jc = ip - 1; j < ipph; ++j, --jc)
+ for (size_t k = 0; k < l1; ++k) {
+ T t1 = CX(0, k, j), t2 = CX(0, k, jc);
+ PM(CX(0, k, j), CX(0, k, jc), t1, t2);
+ for (size_t i = 1; i < ido; ++i) {
+ T x1, x2;
+ PM(x1, x2, CX(i, k, j), CX(i, k, jc));
+ size_t idij = (j - 1) * (ido - 1) + i - 1;
+ special_mul<fwd>(x1, wa[idij], CX(i, k, j));
+ idij = (jc - 1) * (ido - 1) + i - 1;
+ special_mul<fwd>(x2, wa[idij], CX(i, k, jc));
+ }
+ }
+ }
+ }
+
+ template <bool fwd, typename T>
+ void pass_all(T c[], T0 fct) const
+ {
+ if (length == 1) {
+ c[0] *= fct;
+ return;
+ }
+ size_t l1 = 1;
+ arr<T> ch(length);
+ T *p1 = c, *p2 = ch.data();
+
+ for (size_t k1 = 0; k1 < fact.size(); k1++) {
+ size_t ip = fact[k1].fct;
+ size_t l2 = ip * l1;
+ size_t ido = length / l2;
+ if (ip == 4)
+ pass4<fwd>(ido, l1, p1, p2, fact[k1].tw);
+ else if (ip == 8)
+ pass8<fwd>(ido, l1, p1, p2, fact[k1].tw);
+ else if (ip == 2)
+ pass2<fwd>(ido, l1, p1, p2, fact[k1].tw);
+ else if (ip == 3)
+ pass3<fwd>(ido, l1, p1, p2, fact[k1].tw);
+ else if (ip == 5)
+ pass5<fwd>(ido, l1, p1, p2, fact[k1].tw);
+ else if (ip == 7)
+ pass7<fwd>(ido, l1, p1, p2, fact[k1].tw);
+ else if (ip == 11)
+ pass11<fwd>(ido, l1, p1, p2, fact[k1].tw);
+ else {
+ passg<fwd>(ido, ip, l1, p1, p2, fact[k1].tw, fact[k1].tws);
+ std::swap(p1, p2);
+ }
+ std::swap(p1, p2);
+ l1 = l2;
+ }
+ if (p1 != c) {
+ if (fct != 1.)
+ for (size_t i = 0; i < length; ++i)
+ c[i] = ch[i] * fct;
+ else
+ memcpy(c, p1, length * sizeof(T));
+ } else if (fct != 1.)
+ for (size_t i = 0; i < length; ++i)
+ c[i] *= fct;
+ }
+
+ public:
+ template <typename T>
+ void exec(T c[], T0 fct, bool fwd) const
+ {
+ fwd ? pass_all<true>(c, fct) : pass_all<false>(c, fct);
+ }
+
+ private:
+ POCKETFFT_NOINLINE void factorize()
+ {
+ size_t len = length;
+ while ((len & 7) == 0) {
+ add_factor(8);
+ len >>= 3;
+ }
+ while ((len & 3) == 0) {
+ add_factor(4);
+ len >>= 2;
+ }
+ if ((len & 1) == 0) {
+ len >>= 1;
+ // factor 2 should be at the front of the factor list
+ add_factor(2);
+ std::swap(fact[0].fct, fact.back().fct);
+ }
+ for (size_t divisor = 3; divisor * divisor <= len; divisor += 2)
+ while ((len % divisor) == 0) {
+ add_factor(divisor);
+ len /= divisor;
+ }
+ if (len > 1)
+ add_factor(len);
+ }
+
+ size_t twsize() const
+ {
+ size_t twsize = 0, l1 = 1;
+ for (size_t k = 0; k < fact.size(); ++k) {
+ size_t ip = fact[k].fct, ido = length / (l1 * ip);
+ twsize += (ip - 1) * (ido - 1);
+ if (ip > 11)
+ twsize += ip;
+ l1 *= ip;
+ }
+ return twsize;
+ }
+
+ void comp_twiddle()
+ {
+ sincos_2pibyn<T0> twiddle(length);
+ size_t l1 = 1;
+ size_t memofs = 0;
+ for (size_t k = 0; k < fact.size(); ++k) {
+ size_t ip = fact[k].fct, ido = length / (l1 * ip);
+ fact[k].tw = mem.data() + memofs;
+ memofs += (ip - 1) * (ido - 1);
+ for (size_t j = 1; j < ip; ++j)
+ for (size_t i = 1; i < ido; ++i)
+ fact[k].tw[(j - 1) * (ido - 1) + i - 1] = twiddle[j * l1 * i];
+ if (ip > 11) {
+ fact[k].tws = mem.data() + memofs;
+ memofs += ip;
+ for (size_t j = 0; j < ip; ++j)
+ fact[k].tws[j] = twiddle[j * l1 * ido];
+ }
+ l1 *= ip;
+ }
+ }
+
+ public:
+ POCKETFFT_NOINLINE cfftp(size_t length_) : length(length_)
+ {
+ if (length == 0)
+ throw std::runtime_error("zero-length FFT requested");
+ if (length == 1)
+ return;
+ factorize();
+ mem.resize(twsize());
+ comp_twiddle();
+ }
+ };
+
+ //
+ // real-valued FFTPACK transforms
+ //
+
+ template <typename T0>
+ class rfftp
+ {
+ private:
+ struct fctdata {
+ size_t fct;
+ T0 *tw, *tws;
+ };
+
+ size_t length;
+ arr<T0> mem;
+ std::vector<fctdata> fact;
+
+ void add_factor(size_t factor)
+ {
+ fact.push_back({factor, nullptr, nullptr});
+ }
+
+ /* (a+ib) = conj(c+id) * (e+if) */
+ template <typename T1, typename T2, typename T3>
+ inline void MULPM(T1 &a, T1 &b, T2 c, T2 d, T3 e, T3 f) const
+ {
+ a = c * e + d * f;
+ b = c * f - d * e;
+ }
+
+ template <typename T>
+ void radf2(size_t ido, size_t l1, const T *POCKETFFT_RESTRICT cc,
+ T *POCKETFFT_RESTRICT ch,
+ const T0 *POCKETFFT_RESTRICT wa) const
+ {
+ auto WA =
+ [wa, ido](size_t x, size_t i) { return wa[i + x * (ido - 1)]; };
+ auto CC = [cc, ido, l1](size_t a, size_t b, size_t c)
+ -> const T &{ return cc[a + ido * (b + l1 * c)]; };
+ auto CH = [ch, ido](size_t a, size_t b, size_t c)
+ -> T &{ return ch[a + ido * (b + 2 * c)]; };
+
+ for (size_t k = 0; k < l1; k++)
+ PM(CH(0, 0, k), CH(ido - 1, 1, k), CC(0, k, 0), CC(0, k, 1));
+ if ((ido & 1) == 0)
+ for (size_t k = 0; k < l1; k++) {
+ CH(0, 1, k) = -CC(ido - 1, k, 1);
+ CH(ido - 1, 0, k) = CC(ido - 1, k, 0);
+ }
+ if (ido <= 2)
+ return;
+ for (size_t k = 0; k < l1; k++)
+ for (size_t i = 2; i < ido; i += 2) {
+ size_t ic = ido - i;
+ T tr2, ti2;
+ MULPM(tr2, ti2, WA(0, i - 2), WA(0, i - 1), CC(i - 1, k, 1),
+ CC(i, k, 1));
+ PM(CH(i - 1, 0, k), CH(ic - 1, 1, k), CC(i - 1, k, 0), tr2);
+ PM(CH(i, 0, k), CH(ic, 1, k), ti2, CC(i, k, 0));
+ }
+ }
+
+// a2=a+b; b2=i*(b-a);
+#define POCKETFFT_REARRANGE(rx, ix, ry, iy) \
+ { \
+ auto t1 = rx + ry, t2 = ry - rx, t3 = ix + iy, t4 = ix - iy; \
+ rx = t1; \
+ ix = t3; \
+ ry = t4; \
+ iy = t2; \
+ }
+
+ template <typename T>
+ void radf3(size_t ido, size_t l1, const T *POCKETFFT_RESTRICT cc,
+ T *POCKETFFT_RESTRICT ch,
+ const T0 *POCKETFFT_RESTRICT wa) const
+ {
+ constexpr T0 taur = -0.5,
+ taui = T0(0.8660254037844386467637231707529362L);
+
+ auto WA =
+ [wa, ido](size_t x, size_t i) { return wa[i + x * (ido - 1)]; };
+ auto CC = [cc, ido, l1](size_t a, size_t b, size_t c)
+ -> const T &{ return cc[a + ido * (b + l1 * c)]; };
+ auto CH = [ch, ido](size_t a, size_t b, size_t c)
+ -> T &{ return ch[a + ido * (b + 3 * c)]; };
+
+ for (size_t k = 0; k < l1; k++) {
+ T cr2 = CC(0, k, 1) + CC(0, k, 2);
+ CH(0, 0, k) = CC(0, k, 0) + cr2;
+ CH(0, 2, k) = taui * (CC(0, k, 2) - CC(0, k, 1));
+ CH(ido - 1, 1, k) = CC(0, k, 0) + taur * cr2;
+ }
+ if (ido == 1)
+ return;
+ for (size_t k = 0; k < l1; k++)
+ for (size_t i = 2; i < ido; i += 2) {
+ size_t ic = ido - i;
+ T di2, di3, dr2, dr3;
+ MULPM(dr2, di2, WA(0, i - 2), WA(0, i - 1), CC(i - 1, k, 1),
+ CC(i, k, 1)); // d2=conj(WA0)*CC1
+ MULPM(dr3, di3, WA(1, i - 2), WA(1, i - 1), CC(i - 1, k, 2),
+ CC(i, k, 2)); // d3=conj(WA1)*CC2
+ POCKETFFT_REARRANGE(dr2, di2, dr3, di3);
+ CH(i - 1, 0, k) = CC(i - 1, k, 0) + dr2; // c add
+ CH(i, 0, k) = CC(i, k, 0) + di2;
+ T tr2 = CC(i - 1, k, 0) + taur * dr2; // c add
+ T ti2 = CC(i, k, 0) + taur * di2;
+ T tr3 = taui * dr3; // t3 = taui*i*(d3-d2)?
+ T ti3 = taui * di3;
+ PM(CH(i - 1, 2, k), CH(ic - 1, 1, k), tr2, tr3); // PM(i) = t2+t3
+ PM(CH(i, 2, k), CH(ic, 1, k), ti3, ti2); // PM(ic) = conj(t2-t3)
+ }
+ }
+
+ template <typename T>
+ void radf4(size_t ido, size_t l1, const T *POCKETFFT_RESTRICT cc,
+ T *POCKETFFT_RESTRICT ch,
+ const T0 *POCKETFFT_RESTRICT wa) const
+ {
+ constexpr T0 hsqt2 = T0(0.707106781186547524400844362104849L);
+
+ auto WA =
+ [wa, ido](size_t x, size_t i) { return wa[i + x * (ido - 1)]; };
+ auto CC = [cc, ido, l1](size_t a, size_t b, size_t c)
+ -> const T &{ return cc[a + ido * (b + l1 * c)]; };
+ auto CH = [ch, ido](size_t a, size_t b, size_t c)
+ -> T &{ return ch[a + ido * (b + 4 * c)]; };
+
+ for (size_t k = 0; k < l1; k++) {
+ T tr1, tr2;
+ PM(tr1, CH(0, 2, k), CC(0, k, 3), CC(0, k, 1));
+ PM(tr2, CH(ido - 1, 1, k), CC(0, k, 0), CC(0, k, 2));
+ PM(CH(0, 0, k), CH(ido - 1, 3, k), tr2, tr1);
+ }
+ if ((ido & 1) == 0)
+ for (size_t k = 0; k < l1; k++) {
+ T ti1 = -hsqt2 * (CC(ido - 1, k, 1) + CC(ido - 1, k, 3));
+ T tr1 = hsqt2 * (CC(ido - 1, k, 1) - CC(ido - 1, k, 3));
+ PM(CH(ido - 1, 0, k), CH(ido - 1, 2, k), CC(ido - 1, k, 0), tr1);
+ PM(CH(0, 3, k), CH(0, 1, k), ti1, CC(ido - 1, k, 2));
+ }
+ if (ido <= 2)
+ return;
+ for (size_t k = 0; k < l1; k++)
+ for (size_t i = 2; i < ido; i += 2) {
+ size_t ic = ido - i;
+ T ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, tr3,
+ tr4;
+ MULPM(cr2, ci2, WA(0, i - 2), WA(0, i - 1), CC(i - 1, k, 1),
+ CC(i, k, 1));
+ MULPM(cr3, ci3, WA(1, i - 2), WA(1, i - 1), CC(i - 1, k, 2),
+ CC(i, k, 2));
+ MULPM(cr4, ci4, WA(2, i - 2), WA(2, i - 1), CC(i - 1, k, 3),
+ CC(i, k, 3));
+ PM(tr1, tr4, cr4, cr2);
+ PM(ti1, ti4, ci2, ci4);
+ PM(tr2, tr3, CC(i - 1, k, 0), cr3);
+ PM(ti2, ti3, CC(i, k, 0), ci3);
+ PM(CH(i - 1, 0, k), CH(ic - 1, 3, k), tr2, tr1);
+ PM(CH(i, 0, k), CH(ic, 3, k), ti1, ti2);
+ PM(CH(i - 1, 2, k), CH(ic - 1, 1, k), tr3, ti4);
+ PM(CH(i, 2, k), CH(ic, 1, k), tr4, ti3);
+ }
+ }
+
+ template <typename T>
+ void radf5(size_t ido, size_t l1, const T *POCKETFFT_RESTRICT cc,
+ T *POCKETFFT_RESTRICT ch,
+ const T0 *POCKETFFT_RESTRICT wa) const
+ {
+ constexpr T0 tr11 = T0(0.3090169943749474241022934171828191L),
+ ti11 = T0(0.9510565162951535721164393333793821L),
+ tr12 = T0(-0.8090169943749474241022934171828191L),
+ ti12 = T0(0.5877852522924731291687059546390728L);
+
+ auto WA =
+ [wa, ido](size_t x, size_t i) { return wa[i + x * (ido - 1)]; };
+ auto CC = [cc, ido, l1](size_t a, size_t b, size_t c)
+ -> const T &{ return cc[a + ido * (b + l1 * c)]; };
+ auto CH = [ch, ido](size_t a, size_t b, size_t c)
+ -> T &{ return ch[a + ido * (b + 5 * c)]; };
+
+ for (size_t k = 0; k < l1; k++) {
+ T cr2, cr3, ci4, ci5;
+ PM(cr2, ci5, CC(0, k, 4), CC(0, k, 1));
+ PM(cr3, ci4, CC(0, k, 3), CC(0, k, 2));
+ CH(0, 0, k) = CC(0, k, 0) + cr2 + cr3;
+ CH(ido - 1, 1, k) = CC(0, k, 0) + tr11 * cr2 + tr12 * cr3;
+ CH(0, 2, k) = ti11 * ci5 + ti12 * ci4;
+ CH(ido - 1, 3, k) = CC(0, k, 0) + tr12 * cr2 + tr11 * cr3;
+ CH(0, 4, k) = ti12 * ci5 - ti11 * ci4;
+ }
+ if (ido == 1)
+ return;
+ for (size_t k = 0; k < l1; ++k)
+ for (size_t i = 2, ic = ido - 2; i < ido; i += 2, ic -= 2) {
+ T di2, di3, di4, di5, dr2, dr3, dr4, dr5;
+ MULPM(dr2, di2, WA(0, i - 2), WA(0, i - 1), CC(i - 1, k, 1),
+ CC(i, k, 1));
+ MULPM(dr3, di3, WA(1, i - 2), WA(1, i - 1), CC(i - 1, k, 2),
+ CC(i, k, 2));
+ MULPM(dr4, di4, WA(2, i - 2), WA(2, i - 1), CC(i - 1, k, 3),
+ CC(i, k, 3));
+ MULPM(dr5, di5, WA(3, i - 2), WA(3, i - 1), CC(i - 1, k, 4),
+ CC(i, k, 4));
+ POCKETFFT_REARRANGE(dr2, di2, dr5, di5);
+ POCKETFFT_REARRANGE(dr3, di3, dr4, di4);
+ CH(i - 1, 0, k) = CC(i - 1, k, 0) + dr2 + dr3;
+ CH(i, 0, k) = CC(i, k, 0) + di2 + di3;
+ T tr2 = CC(i - 1, k, 0) + tr11 * dr2 + tr12 * dr3;
+ T ti2 = CC(i, k, 0) + tr11 * di2 + tr12 * di3;
+ T tr3 = CC(i - 1, k, 0) + tr12 * dr2 + tr11 * dr3;
+ T ti3 = CC(i, k, 0) + tr12 * di2 + tr11 * di3;
+ T tr5 = ti11 * dr5 + ti12 * dr4;
+ T ti5 = ti11 * di5 + ti12 * di4;
+ T tr4 = ti12 * dr5 - ti11 * dr4;
+ T ti4 = ti12 * di5 - ti11 * di4;
+ PM(CH(i - 1, 2, k), CH(ic - 1, 1, k), tr2, tr5);
+ PM(CH(i, 2, k), CH(ic, 1, k), ti5, ti2);
+ PM(CH(i - 1, 4, k), CH(ic - 1, 3, k), tr3, tr4);
+ PM(CH(i, 4, k), CH(ic, 3, k), ti4, ti3);
+ }
+ }
+
+#undef POCKETFFT_REARRANGE
+
+ template <typename T>
+ void radfg(size_t ido, size_t ip, size_t l1, T *POCKETFFT_RESTRICT cc,
+ T *POCKETFFT_RESTRICT ch, const T0 *POCKETFFT_RESTRICT wa,
+ const T0 *POCKETFFT_RESTRICT csarr) const
+ {
+ const size_t cdim = ip;
+ size_t ipph = (ip + 1) / 2;
+ size_t idl1 = ido * l1;
+
+ auto CC = [cc, ido, cdim](size_t a, size_t b, size_t c)
+ -> T &{ return cc[a + ido * (b + cdim * c)]; };
+ auto CH = [ch, ido, l1](size_t a, size_t b, size_t c)
+ -> const T &{ return ch[a + ido * (b + l1 * c)]; };
+ auto C1 = [cc, ido, l1](size_t a, size_t b, size_t c)
+ -> T &{ return cc[a + ido * (b + l1 * c)]; };
+ auto C2 =
+ [cc, idl1](size_t a, size_t b) -> T &{ return cc[a + idl1 * b]; };
+ auto CH2 =
+ [ch, idl1](size_t a, size_t b) -> T &{ return ch[a + idl1 * b]; };
+
+ if (ido > 1) {
+ for (size_t j = 1, jc = ip - 1; j < ipph; ++j, --jc) // 114
+ {
+ size_t is = (j - 1) * (ido - 1), is2 = (jc - 1) * (ido - 1);
+ for (size_t k = 0; k < l1; ++k) // 113
+ {
+ size_t idij = is;
+ size_t idij2 = is2;
+ for (size_t i = 1; i <= ido - 2; i += 2) // 112
+ {
+ T t1 = C1(i, k, j), t2 = C1(i + 1, k, j), t3 = C1(i, k, jc),
+ t4 = C1(i + 1, k, jc);
+ T x1 = wa[idij] * t1 + wa[idij + 1] * t2,
+ x2 = wa[idij] * t2 - wa[idij + 1] * t1,
+ x3 = wa[idij2] * t3 + wa[idij2 + 1] * t4,
+ x4 = wa[idij2] * t4 - wa[idij2 + 1] * t3;
+ PM(C1(i, k, j), C1(i + 1, k, jc), x3, x1);
+ PM(C1(i + 1, k, j), C1(i, k, jc), x2, x4);
+ idij += 2;
+ idij2 += 2;
+ }
+ }
+ }
+ }
+
+ for (size_t j = 1, jc = ip - 1; j < ipph; ++j, --jc) // 123
+ for (size_t k = 0; k < l1; ++k) // 122
+ MPINPLACE(C1(0, k, jc), C1(0, k, j));
+
+ // everything in C
+ // memset(ch,0,ip*l1*ido*sizeof(double));
+
+ for (size_t l = 1, lc = ip - 1; l < ipph; ++l, --lc) // 127
+ {
+ for (size_t ik = 0; ik < idl1; ++ik) // 124
+ {
+ CH2(ik, l) =
+ C2(ik, 0) + csarr[2 * l] * C2(ik, 1) + csarr[4 * l] * C2(ik, 2);
+ CH2(ik, lc) = csarr[2 * l + 1] * C2(ik, ip - 1) +
+ csarr[4 * l + 1] * C2(ik, ip - 2);
+ }
+ size_t iang = 2 * l;
+ size_t j = 3, jc = ip - 3;
+ for (; j < ipph - 3; j += 4, jc -= 4) // 126
+ {
+ iang += l;
+ if (iang >= ip)
+ iang -= ip;
+ T0 ar1 = csarr[2 * iang], ai1 = csarr[2 * iang + 1];
+ iang += l;
+ if (iang >= ip)
+ iang -= ip;
+ T0 ar2 = csarr[2 * iang], ai2 = csarr[2 * iang + 1];
+ iang += l;
+ if (iang >= ip)
+ iang -= ip;
+ T0 ar3 = csarr[2 * iang], ai3 = csarr[2 * iang + 1];
+ iang += l;
+ if (iang >= ip)
+ iang -= ip;
+ T0 ar4 = csarr[2 * iang], ai4 = csarr[2 * iang + 1];
+ for (size_t ik = 0; ik < idl1; ++ik) // 125
+ {
+ CH2(ik, l) += ar1 * C2(ik, j) + ar2 * C2(ik, j + 1) +
+ ar3 * C2(ik, j + 2) + ar4 * C2(ik, j + 3);
+ CH2(ik, lc) += ai1 * C2(ik, jc) + ai2 * C2(ik, jc - 1) +
+ ai3 * C2(ik, jc - 2) + ai4 * C2(ik, jc - 3);
+ }
+ }
+ for (; j < ipph - 1; j += 2, jc -= 2) // 126
+ {
+ iang += l;
+ if (iang >= ip)
+ iang -= ip;
+ T0 ar1 = csarr[2 * iang], ai1 = csarr[2 * iang + 1];
+ iang += l;
+ if (iang >= ip)
+ iang -= ip;
+ T0 ar2 = csarr[2 * iang], ai2 = csarr[2 * iang + 1];
+ for (size_t ik = 0; ik < idl1; ++ik) // 125
+ {
+ CH2(ik, l) += ar1 * C2(ik, j) + ar2 * C2(ik, j + 1);
+ CH2(ik, lc) += ai1 * C2(ik, jc) + ai2 * C2(ik, jc - 1);
+ }
+ }
+ for (; j < ipph; ++j, --jc) // 126
+ {
+ iang += l;
+ if (iang >= ip)
+ iang -= ip;
+ T0 ar = csarr[2 * iang], ai = csarr[2 * iang + 1];
+ for (size_t ik = 0; ik < idl1; ++ik) // 125
+ {
+ CH2(ik, l) += ar * C2(ik, j);
+ CH2(ik, lc) += ai * C2(ik, jc);
+ }
+ }
+ }
+ for (size_t ik = 0; ik < idl1; ++ik) // 101
+ CH2(ik, 0) = C2(ik, 0);
+ for (size_t j = 1; j < ipph; ++j) // 129
+ for (size_t ik = 0; ik < idl1; ++ik) // 128
+ CH2(ik, 0) += C2(ik, j);
+
+ // everything in CH at this point!
+ // memset(cc,0,ip*l1*ido*sizeof(double));
+
+ for (size_t k = 0; k < l1; ++k) // 131
+ for (size_t i = 0; i < ido; ++i) // 130
+ CC(i, 0, k) = CH(i, k, 0);
+
+ for (size_t j = 1, jc = ip - 1; j < ipph; ++j, --jc) // 137
+ {
+ size_t j2 = 2 * j - 1;
+ for (size_t k = 0; k < l1; ++k) // 136
+ {
+ CC(ido - 1, j2, k) = CH(0, k, j);
+ CC(0, j2 + 1, k) = CH(0, k, jc);
+ }
+ }
+
+ if (ido == 1)
+ return;
+
+ for (size_t j = 1, jc = ip - 1; j < ipph; ++j, --jc) // 140
+ {
+ size_t j2 = 2 * j - 1;
+ for (size_t k = 0; k < l1; ++k) // 139
+ for (size_t i = 1, ic = ido - i - 2; i <= ido - 2;
+ i += 2, ic -= 2) // 138
+ {
+ CC(i, j2 + 1, k) = CH(i, k, j) + CH(i, k, jc);
+ CC(ic, j2, k) = CH(i, k, j) - CH(i, k, jc);
+ CC(i + 1, j2 + 1, k) = CH(i + 1, k, j) + CH(i + 1, k, jc);
+ CC(ic + 1, j2, k) = CH(i + 1, k, jc) - CH(i + 1, k, j);
+ }
+ }
+ }
+
+ template <typename T>
+ void radb2(size_t ido, size_t l1, const T *POCKETFFT_RESTRICT cc,
+ T *POCKETFFT_RESTRICT ch,
+ const T0 *POCKETFFT_RESTRICT wa) const
+ {
+ auto WA =
+ [wa, ido](size_t x, size_t i) { return wa[i + x * (ido - 1)]; };
+ auto CC = [cc, ido](size_t a, size_t b, size_t c)
+ -> const T &{ return cc[a + ido * (b + 2 * c)]; };
+ auto CH = [ch, ido, l1](size_t a, size_t b, size_t c)
+ -> T &{ return ch[a + ido * (b + l1 * c)]; };
+
+ for (size_t k = 0; k < l1; k++)
+ PM(CH(0, k, 0), CH(0, k, 1), CC(0, 0, k), CC(ido - 1, 1, k));
+ if ((ido & 1) == 0)
+ for (size_t k = 0; k < l1; k++) {
+ CH(ido - 1, k, 0) = 2 * CC(ido - 1, 0, k);
+ CH(ido - 1, k, 1) = -2 * CC(0, 1, k);
+ }
+ if (ido <= 2)
+ return;
+ for (size_t k = 0; k < l1; ++k)
+ for (size_t i = 2; i < ido; i += 2) {
+ size_t ic = ido - i;
+ T ti2, tr2;
+ PM(CH(i - 1, k, 0), tr2, CC(i - 1, 0, k), CC(ic - 1, 1, k));
+ PM(ti2, CH(i, k, 0), CC(i, 0, k), CC(ic, 1, k));
+ MULPM(CH(i, k, 1), CH(i - 1, k, 1), WA(0, i - 2), WA(0, i - 1), ti2,
+ tr2);
+ }
+ }
+
+ template <typename T>
+ void radb3(size_t ido, size_t l1, const T *POCKETFFT_RESTRICT cc,
+ T *POCKETFFT_RESTRICT ch,
+ const T0 *POCKETFFT_RESTRICT wa) const
+ {
+ constexpr T0 taur = -0.5,
+ taui = T0(0.8660254037844386467637231707529362L);
+
+ auto WA =
+ [wa, ido](size_t x, size_t i) { return wa[i + x * (ido - 1)]; };
+ auto CC = [cc, ido](size_t a, size_t b, size_t c)
+ -> const T &{ return cc[a + ido * (b + 3 * c)]; };
+ auto CH = [ch, ido, l1](size_t a, size_t b, size_t c)
+ -> T &{ return ch[a + ido * (b + l1 * c)]; };
+
+ for (size_t k = 0; k < l1; k++) {
+ T tr2 = 2 * CC(ido - 1, 1, k);
+ T cr2 = CC(0, 0, k) + taur * tr2;
+ CH(0, k, 0) = CC(0, 0, k) + tr2;
+ T ci3 = 2 * taui * CC(0, 2, k);
+ PM(CH(0, k, 2), CH(0, k, 1), cr2, ci3);
+ }
+ if (ido == 1)
+ return;
+ for (size_t k = 0; k < l1; k++)
+ for (size_t i = 2, ic = ido - 2; i < ido; i += 2, ic -= 2) {
+ T tr2 =
+ CC(i - 1, 2, k) + CC(ic - 1, 1, k); // t2=CC(I) + conj(CC(ic))
+ T ti2 = CC(i, 2, k) - CC(ic, 1, k);
+ T cr2 = CC(i - 1, 0, k) + taur * tr2; // c2=CC +taur*t2
+ T ci2 = CC(i, 0, k) + taur * ti2;
+ CH(i - 1, k, 0) = CC(i - 1, 0, k) + tr2; // CH=CC+t2
+ CH(i, k, 0) = CC(i, 0, k) + ti2;
+ T cr3 = taui * (CC(i - 1, 2, k) -
+ CC(ic - 1, 1, k)); // c3=taui*(CC(i)-conj(CC(ic)))
+ T ci3 = taui * (CC(i, 2, k) + CC(ic, 1, k));
+ T di2, di3, dr2, dr3;
+ PM(dr3, dr2, cr2, ci3); // d2= (cr2-ci3, ci2+cr3) = c2+i*c3
+ PM(di2, di3, ci2, cr3); // d3= (cr2+ci3, ci2-cr3) = c2-i*c3
+ MULPM(CH(i, k, 1), CH(i - 1, k, 1), WA(0, i - 2), WA(0, i - 1), di2,
+ dr2); // ch = WA*d2
+ MULPM(CH(i, k, 2), CH(i - 1, k, 2), WA(1, i - 2), WA(1, i - 1), di3,
+ dr3);
+ }
+ }
+
+ template <typename T>
+ void radb4(size_t ido, size_t l1, const T *POCKETFFT_RESTRICT cc,
+ T *POCKETFFT_RESTRICT ch,
+ const T0 *POCKETFFT_RESTRICT wa) const
+ {
+ constexpr T0 sqrt2 = T0(1.414213562373095048801688724209698L);
+
+ auto WA =
+ [wa, ido](size_t x, size_t i) { return wa[i + x * (ido - 1)]; };
+ auto CC = [cc, ido](size_t a, size_t b, size_t c)
+ -> const T &{ return cc[a + ido * (b + 4 * c)]; };
+ auto CH = [ch, ido, l1](size_t a, size_t b, size_t c)
+ -> T &{ return ch[a + ido * (b + l1 * c)]; };
+
+ for (size_t k = 0; k < l1; k++) {
+ T tr1, tr2;
+ PM(tr2, tr1, CC(0, 0, k), CC(ido - 1, 3, k));
+ T tr3 = 2 * CC(ido - 1, 1, k);
+ T tr4 = 2 * CC(0, 2, k);
+ PM(CH(0, k, 0), CH(0, k, 2), tr2, tr3);
+ PM(CH(0, k, 3), CH(0, k, 1), tr1, tr4);
+ }
+ if ((ido & 1) == 0)
+ for (size_t k = 0; k < l1; k++) {
+ T tr1, tr2, ti1, ti2;
+ PM(ti1, ti2, CC(0, 3, k), CC(0, 1, k));
+ PM(tr2, tr1, CC(ido - 1, 0, k), CC(ido - 1, 2, k));
+ CH(ido - 1, k, 0) = tr2 + tr2;
+ CH(ido - 1, k, 1) = sqrt2 * (tr1 - ti1);
+ CH(ido - 1, k, 2) = ti2 + ti2;
+ CH(ido - 1, k, 3) = -sqrt2 * (tr1 + ti1);
+ }
+ if (ido <= 2)
+ return;
+ for (size_t k = 0; k < l1; ++k)
+ for (size_t i = 2; i < ido; i += 2) {
+ T ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, tr3,
+ tr4;
+ size_t ic = ido - i;
+ PM(tr2, tr1, CC(i - 1, 0, k), CC(ic - 1, 3, k));
+ PM(ti1, ti2, CC(i, 0, k), CC(ic, 3, k));
+ PM(tr4, ti3, CC(i, 2, k), CC(ic, 1, k));
+ PM(tr3, ti4, CC(i - 1, 2, k), CC(ic - 1, 1, k));
+ PM(CH(i - 1, k, 0), cr3, tr2, tr3);
+ PM(CH(i, k, 0), ci3, ti2, ti3);
+ PM(cr4, cr2, tr1, tr4);
+ PM(ci2, ci4, ti1, ti4);
+ MULPM(CH(i, k, 1), CH(i - 1, k, 1), WA(0, i - 2), WA(0, i - 1), ci2,
+ cr2);
+ MULPM(CH(i, k, 2), CH(i - 1, k, 2), WA(1, i - 2), WA(1, i - 1), ci3,
+ cr3);
+ MULPM(CH(i, k, 3), CH(i - 1, k, 3), WA(2, i - 2), WA(2, i - 1), ci4,
+ cr4);
+ }
+ }
+
+ template <typename T>
+ void radb5(size_t ido, size_t l1, const T *POCKETFFT_RESTRICT cc,
+ T *POCKETFFT_RESTRICT ch,
+ const T0 *POCKETFFT_RESTRICT wa) const
+ {
+ constexpr T0 tr11 = T0(0.3090169943749474241022934171828191L),
+ ti11 = T0(0.9510565162951535721164393333793821L),
+ tr12 = T0(-0.8090169943749474241022934171828191L),
+ ti12 = T0(0.5877852522924731291687059546390728L);
+
+ auto WA =
+ [wa, ido](size_t x, size_t i) { return wa[i + x * (ido - 1)]; };
+ auto CC = [cc, ido](size_t a, size_t b, size_t c)
+ -> const T &{ return cc[a + ido * (b + 5 * c)]; };
+ auto CH = [ch, ido, l1](size_t a, size_t b, size_t c)
+ -> T &{ return ch[a + ido * (b + l1 * c)]; };
+
+ for (size_t k = 0; k < l1; k++) {
+ T ti5 = CC(0, 2, k) + CC(0, 2, k);
+ T ti4 = CC(0, 4, k) + CC(0, 4, k);
+ T tr2 = CC(ido - 1, 1, k) + CC(ido - 1, 1, k);
+ T tr3 = CC(ido - 1, 3, k) + CC(ido - 1, 3, k);
+ CH(0, k, 0) = CC(0, 0, k) + tr2 + tr3;
+ T cr2 = CC(0, 0, k) + tr11 * tr2 + tr12 * tr3;
+ T cr3 = CC(0, 0, k) + tr12 * tr2 + tr11 * tr3;
+ T ci4, ci5;
+ MULPM(ci5, ci4, ti5, ti4, ti11, ti12);
+ PM(CH(0, k, 4), CH(0, k, 1), cr2, ci5);
+ PM(CH(0, k, 3), CH(0, k, 2), cr3, ci4);
+ }
+ if (ido == 1)
+ return;
+ for (size_t k = 0; k < l1; ++k)
+ for (size_t i = 2, ic = ido - 2; i < ido; i += 2, ic -= 2) {
+ T tr2, tr3, tr4, tr5, ti2, ti3, ti4, ti5;
+ PM(tr2, tr5, CC(i - 1, 2, k), CC(ic - 1, 1, k));
+ PM(ti5, ti2, CC(i, 2, k), CC(ic, 1, k));
+ PM(tr3, tr4, CC(i - 1, 4, k), CC(ic - 1, 3, k));
+ PM(ti4, ti3, CC(i, 4, k), CC(ic, 3, k));
+ CH(i - 1, k, 0) = CC(i - 1, 0, k) + tr2 + tr3;
+ CH(i, k, 0) = CC(i, 0, k) + ti2 + ti3;
+ T cr2 = CC(i - 1, 0, k) + tr11 * tr2 + tr12 * tr3;
+ T ci2 = CC(i, 0, k) + tr11 * ti2 + tr12 * ti3;
+ T cr3 = CC(i - 1, 0, k) + tr12 * tr2 + tr11 * tr3;
+ T ci3 = CC(i, 0, k) + tr12 * ti2 + tr11 * ti3;
+ T ci4, ci5, cr5, cr4;
+ MULPM(cr5, cr4, tr5, tr4, ti11, ti12);
+ MULPM(ci5, ci4, ti5, ti4, ti11, ti12);
+ T dr2, dr3, dr4, dr5, di2, di3, di4, di5;
+ PM(dr4, dr3, cr3, ci4);
+ PM(di3, di4, ci3, cr4);
+ PM(dr5, dr2, cr2, ci5);
+ PM(di2, di5, ci2, cr5);
+ MULPM(CH(i, k, 1), CH(i - 1, k, 1), WA(0, i - 2), WA(0, i - 1), di2,
+ dr2);
+ MULPM(CH(i, k, 2), CH(i - 1, k, 2), WA(1, i - 2), WA(1, i - 1), di3,
+ dr3);
+ MULPM(CH(i, k, 3), CH(i - 1, k, 3), WA(2, i - 2), WA(2, i - 1), di4,
+ dr4);
+ MULPM(CH(i, k, 4), CH(i - 1, k, 4), WA(3, i - 2), WA(3, i - 1), di5,
+ dr5);
+ }
+ }
+
+ template <typename T>
+ void radbg(size_t ido, size_t ip, size_t l1, T *POCKETFFT_RESTRICT cc,
+ T *POCKETFFT_RESTRICT ch, const T0 *POCKETFFT_RESTRICT wa,
+ const T0 *POCKETFFT_RESTRICT csarr) const
+ {
+ const size_t cdim = ip;
+ size_t ipph = (ip + 1) / 2;
+ size_t idl1 = ido * l1;
+
+ auto CC = [cc, ido, cdim](size_t a, size_t b, size_t c)
+ -> const T &{ return cc[a + ido * (b + cdim * c)]; };
+ auto CH = [ch, ido, l1](size_t a, size_t b, size_t c)
+ -> T &{ return ch[a + ido * (b + l1 * c)]; };
+ auto C1 = [cc, ido, l1](size_t a, size_t b, size_t c)
+ -> const T &{ return cc[a + ido * (b + l1 * c)]; };
+ auto C2 =
+ [cc, idl1](size_t a, size_t b) -> T &{ return cc[a + idl1 * b]; };
+ auto CH2 =
+ [ch, idl1](size_t a, size_t b) -> T &{ return ch[a + idl1 * b]; };
+
+ for (size_t k = 0; k < l1; ++k) // 102
+ for (size_t i = 0; i < ido; ++i) // 101
+ CH(i, k, 0) = CC(i, 0, k);
+ for (size_t j = 1, jc = ip - 1; j < ipph; ++j, --jc) // 108
+ {
+ size_t j2 = 2 * j - 1;
+ for (size_t k = 0; k < l1; ++k) {
+ CH(0, k, j) = 2 * CC(ido - 1, j2, k);
+ CH(0, k, jc) = 2 * CC(0, j2 + 1, k);
+ }
+ }
+
+ if (ido != 1) {
+ for (size_t j = 1, jc = ip - 1; j < ipph; ++j, --jc) // 111
+ {
+ size_t j2 = 2 * j - 1;
+ for (size_t k = 0; k < l1; ++k)
+ for (size_t i = 1, ic = ido - i - 2; i <= ido - 2;
+ i += 2, ic -= 2) // 109
+ {
+ CH(i, k, j) = CC(i, j2 + 1, k) + CC(ic, j2, k);
+ CH(i, k, jc) = CC(i, j2 + 1, k) - CC(ic, j2, k);
+ CH(i + 1, k, j) = CC(i + 1, j2 + 1, k) - CC(ic + 1, j2, k);
+ CH(i + 1, k, jc) = CC(i + 1, j2 + 1, k) + CC(ic + 1, j2, k);
+ }
+ }
+ }
+ for (size_t l = 1, lc = ip - 1; l < ipph; ++l, --lc) {
+ for (size_t ik = 0; ik < idl1; ++ik) {
+ C2(ik, l) = CH2(ik, 0) + csarr[2 * l] * CH2(ik, 1) +
+ csarr[4 * l] * CH2(ik, 2);
+ C2(ik, lc) = csarr[2 * l + 1] * CH2(ik, ip - 1) +
+ csarr[4 * l + 1] * CH2(ik, ip - 2);
+ }
+ size_t iang = 2 * l;
+ size_t j = 3, jc = ip - 3;
+ for (; j < ipph - 3; j += 4, jc -= 4) {
+ iang += l;
+ if (iang > ip)
+ iang -= ip;
+ T0 ar1 = csarr[2 * iang], ai1 = csarr[2 * iang + 1];
+ iang += l;
+ if (iang > ip)
+ iang -= ip;
+ T0 ar2 = csarr[2 * iang], ai2 = csarr[2 * iang + 1];
+ iang += l;
+ if (iang > ip)
+ iang -= ip;
+ T0 ar3 = csarr[2 * iang], ai3 = csarr[2 * iang + 1];
+ iang += l;
+ if (iang > ip)
+ iang -= ip;
+ T0 ar4 = csarr[2 * iang], ai4 = csarr[2 * iang + 1];
+ for (size_t ik = 0; ik < idl1; ++ik) {
+ C2(ik, l) += ar1 * CH2(ik, j) + ar2 * CH2(ik, j + 1) +
+ ar3 * CH2(ik, j + 2) + ar4 * CH2(ik, j + 3);
+ C2(ik, lc) += ai1 * CH2(ik, jc) + ai2 * CH2(ik, jc - 1) +
+ ai3 * CH2(ik, jc - 2) + ai4 * CH2(ik, jc - 3);
+ }
+ }
+ for (; j < ipph - 1; j += 2, jc -= 2) {
+ iang += l;
+ if (iang > ip)
+ iang -= ip;
+ T0 ar1 = csarr[2 * iang], ai1 = csarr[2 * iang + 1];
+ iang += l;
+ if (iang > ip)
+ iang -= ip;
+ T0 ar2 = csarr[2 * iang], ai2 = csarr[2 * iang + 1];
+ for (size_t ik = 0; ik < idl1; ++ik) {
+ C2(ik, l) += ar1 * CH2(ik, j) + ar2 * CH2(ik, j + 1);
+ C2(ik, lc) += ai1 * CH2(ik, jc) + ai2 * CH2(ik, jc - 1);
+ }
+ }
+ for (; j < ipph; ++j, --jc) {
+ iang += l;
+ if (iang > ip)
+ iang -= ip;
+ T0 war = csarr[2 * iang], wai = csarr[2 * iang + 1];
+ for (size_t ik = 0; ik < idl1; ++ik) {
+ C2(ik, l) += war * CH2(ik, j);
+ C2(ik, lc) += wai * CH2(ik, jc);
+ }
+ }
+ }
+ for (size_t j = 1; j < ipph; ++j)
+ for (size_t ik = 0; ik < idl1; ++ik)
+ CH2(ik, 0) += CH2(ik, j);
+ for (size_t j = 1, jc = ip - 1; j < ipph; ++j, --jc) // 124
+ for (size_t k = 0; k < l1; ++k)
+ PM(CH(0, k, jc), CH(0, k, j), C1(0, k, j), C1(0, k, jc));
+
+ if (ido == 1)
+ return;
+
+ for (size_t j = 1, jc = ip - 1; j < ipph; ++j, --jc) // 127
+ for (size_t k = 0; k < l1; ++k)
+ for (size_t i = 1; i <= ido - 2; i += 2) {
+ CH(i, k, j) = C1(i, k, j) - C1(i + 1, k, jc);
+ CH(i, k, jc) = C1(i, k, j) + C1(i + 1, k, jc);
+ CH(i + 1, k, j) = C1(i + 1, k, j) + C1(i, k, jc);
+ CH(i + 1, k, jc) = C1(i + 1, k, j) - C1(i, k, jc);
+ }
+
+ // All in CH
+
+ for (size_t j = 1; j < ip; ++j) {
+ size_t is = (j - 1) * (ido - 1);
+ for (size_t k = 0; k < l1; ++k) {
+ size_t idij = is;
+ for (size_t i = 1; i <= ido - 2; i += 2) {
+ T t1 = CH(i, k, j), t2 = CH(i + 1, k, j);
+ CH(i, k, j) = wa[idij] * t1 - wa[idij + 1] * t2;
+ CH(i + 1, k, j) = wa[idij] * t2 + wa[idij + 1] * t1;
+ idij += 2;
+ }
+ }
+ }
+ }
+
+ template <typename T>
+ void copy_and_norm(T *c, T *p1, size_t n, T0 fct) const
+ {
+ if (p1 != c) {
+ if (fct != 1.)
+ for (size_t i = 0; i < n; ++i)
+ c[i] = fct * p1[i];
+ else
+ memcpy(c, p1, n * sizeof(T));
+ } else if (fct != 1.)
+ for (size_t i = 0; i < n; ++i)
+ c[i] *= fct;
+ }
+
+ public:
+ template <typename T>
+ void exec(T c[], T0 fct, bool r2hc) const
+ {
+ if (length == 1) {
+ c[0] *= fct;
+ return;
+ }
+ size_t n = length, nf = fact.size();
+ arr<T> ch(n);
+ T *p1 = c, *p2 = ch.data();
+
+ if (r2hc)
+ for (size_t k1 = 0, l1 = n; k1 < nf; ++k1) {
+ size_t k = nf - k1 - 1;
+ size_t ip = fact[k].fct;
+ size_t ido = n / l1;
+ l1 /= ip;
+ if (ip == 4)
+ radf4(ido, l1, p1, p2, fact[k].tw);
+ else if (ip == 2)
+ radf2(ido, l1, p1, p2, fact[k].tw);
+ else if (ip == 3)
+ radf3(ido, l1, p1, p2, fact[k].tw);
+ else if (ip == 5)
+ radf5(ido, l1, p1, p2, fact[k].tw);
+ else {
+ radfg(ido, ip, l1, p1, p2, fact[k].tw, fact[k].tws);
+ std::swap(p1, p2);
+ }
+ std::swap(p1, p2);
+ }
+ else
+ for (size_t k = 0, l1 = 1; k < nf; k++) {
+ size_t ip = fact[k].fct, ido = n / (ip * l1);
+ if (ip == 4)
+ radb4(ido, l1, p1, p2, fact[k].tw);
+ else if (ip == 2)
+ radb2(ido, l1, p1, p2, fact[k].tw);
+ else if (ip == 3)
+ radb3(ido, l1, p1, p2, fact[k].tw);
+ else if (ip == 5)
+ radb5(ido, l1, p1, p2, fact[k].tw);
+ else
+ radbg(ido, ip, l1, p1, p2, fact[k].tw, fact[k].tws);
+ std::swap(p1, p2);
+ l1 *= ip;
+ }
+
+ copy_and_norm(c, p1, n, fct);
+ }
+
+ private:
+ void factorize()
+ {
+ size_t len = length;
+ while ((len % 4) == 0) {
+ add_factor(4);
+ len >>= 2;
+ }
+ if ((len % 2) == 0) {
+ len >>= 1;
+ // factor 2 should be at the front of the factor list
+ add_factor(2);
+ std::swap(fact[0].fct, fact.back().fct);
+ }
+ for (size_t divisor = 3; divisor * divisor <= len; divisor += 2)
+ while ((len % divisor) == 0) {
+ add_factor(divisor);
+ len /= divisor;
+ }
+ if (len > 1)
+ add_factor(len);
+ }
+
+ size_t twsize() const
+ {
+ size_t twsz = 0, l1 = 1;
+ for (size_t k = 0; k < fact.size(); ++k) {
+ size_t ip = fact[k].fct, ido = length / (l1 * ip);
+ twsz += (ip - 1) * (ido - 1);
+ if (ip > 5)
+ twsz += 2 * ip;
+ l1 *= ip;
+ }
+ return twsz;
+ }
+
+ void comp_twiddle()
+ {
+ sincos_2pibyn<T0> twid(length);
+ size_t l1 = 1;
+ T0 *ptr = mem.data();
+ for (size_t k = 0; k < fact.size(); ++k) {
+ size_t ip = fact[k].fct, ido = length / (l1 * ip);
+ if (k < fact.size() - 1) // last factor doesn't need twiddles
+ {
+ fact[k].tw = ptr;
+ ptr += (ip - 1) * (ido - 1);
+ for (size_t j = 1; j < ip; ++j)
+ for (size_t i = 1; i <= (ido - 1) / 2; ++i) {
+ fact[k].tw[(j - 1) * (ido - 1) + 2 * i - 2] =
+ twid[j * l1 * i].r;
+ fact[k].tw[(j - 1) * (ido - 1) + 2 * i - 1] =
+ twid[j * l1 * i].i;
+ }
+ }
+ if (ip > 5) // special factors required by *g functions
+ {
+ fact[k].tws = ptr;
+ ptr += 2 * ip;
+ fact[k].tws[0] = 1.;
+ fact[k].tws[1] = 0.;
+ for (size_t i = 2, ic = 2 * ip - 2; i <= ic; i += 2, ic -= 2) {
+ fact[k].tws[i] = twid[i / 2 * (length / ip)].r;
+ fact[k].tws[i + 1] = twid[i / 2 * (length / ip)].i;
+ fact[k].tws[ic] = twid[i / 2 * (length / ip)].r;
+ fact[k].tws[ic + 1] = -twid[i / 2 * (length / ip)].i;
+ }
+ }
+ l1 *= ip;
+ }
+ }
+
+ public:
+ POCKETFFT_NOINLINE rfftp(size_t length_) : length(length_)
+ {
+ if (length == 0)
+ throw std::runtime_error("zero-length FFT requested");
+ if (length == 1)
+ return;
+ factorize();
+ mem.resize(twsize());
+ comp_twiddle();
+ }
+ };
+
+ //
+ // complex Bluestein transforms
+ //
+
+ template <typename T0>
+ class fftblue
+ {
+ private:
+ size_t n, n2;
+ cfftp<T0> plan;
+ arr<cmplx<T0>> mem;
+ cmplx<T0> *bk, *bkf;
+
+ template <bool fwd, typename T>
+ void fft(cmplx<T> c[], T0 fct) const
+ {
+ arr<cmplx<T>> akf(n2);
+
+ /* initialize a_k and FFT it */
+ for (size_t m = 0; m < n; ++m)
+ special_mul<fwd>(c[m], bk[m], akf[m]);
+ auto zero = akf[0] * T0(0);
+ for (size_t m = n; m < n2; ++m)
+ akf[m] = zero;
+
+ plan.exec(akf.data(), 1., true);
+
+ /* do the convolution */
+ akf[0] = akf[0].template special_mul<!fwd>(bkf[0]);
+ for (size_t m = 1; m < (n2 + 1) / 2; ++m) {
+ akf[m] = akf[m].template special_mul<!fwd>(bkf[m]);
+ akf[n2 - m] = akf[n2 - m].template special_mul<!fwd>(bkf[m]);
+ }
+ if ((n2 & 1) == 0)
+ akf[n2 / 2] = akf[n2 / 2].template special_mul<!fwd>(bkf[n2 / 2]);
+
+ /* inverse FFT */
+ plan.exec(akf.data(), 1., false);
+
+ /* multiply by b_k */
+ for (size_t m = 0; m < n; ++m)
+ c[m] = akf[m].template special_mul<fwd>(bk[m]) * fct;
+ }
+
+ public:
+ POCKETFFT_NOINLINE fftblue(size_t length)
+ : n(length), n2(util::good_size_cmplx(n * 2 - 1)), plan(n2),
+ mem(n + n2 / 2 + 1), bk(mem.data()), bkf(mem.data() + n)
+ {
+ /* initialize b_k */
+ sincos_2pibyn<T0> tmp(2 * n);
+ bk[0].Set(1, 0);
+
+ size_t coeff = 0;
+ for (size_t m = 1; m < n; ++m) {
+ coeff += 2 * m - 1;
+ if (coeff >= 2 * n)
+ coeff -= 2 * n;
+ bk[m] = tmp[coeff];
+ }
+
+ /* initialize the zero-padded, Fourier transformed b_k. Add
+ * normalisation. */
+ arr<cmplx<T0>> tbkf(n2);
+ T0 xn2 = T0(1) / T0(n2);
+ tbkf[0] = bk[0] * xn2;
+ for (size_t m = 1; m < n; ++m)
+ tbkf[m] = tbkf[n2 - m] = bk[m] * xn2;
+ for (size_t m = n; m <= (n2 - n); ++m)
+ tbkf[m].Set(0., 0.);
+ plan.exec(tbkf.data(), 1., true);
+ for (size_t i = 0; i < n2 / 2 + 1; ++i)
+ bkf[i] = tbkf[i];
+ }
+
+ template <typename T>
+ void exec(cmplx<T> c[], T0 fct, bool fwd) const
+ {
+ fwd ? fft<true>(c, fct) : fft<false>(c, fct);
+ }
+
+ template <typename T>
+ void exec_r(T c[], T0 fct, bool fwd)
+ {
+ arr<cmplx<T>> tmp(n);
+ if (fwd) {
+ auto zero = T0(0) * c[0];
+ for (size_t m = 0; m < n; ++m)
+ tmp[m].Set(c[m], zero);
+ fft<true>(tmp.data(), fct);
+ c[0] = tmp[0].r;
+ memcpy(c + 1, tmp.data() + 1, (n - 1) * sizeof(T));
+ } else {
+ tmp[0].Set(c[0], c[0] * 0);
+ memcpy(reinterpret_cast<void *>(tmp.data() + 1),
+ reinterpret_cast<void *>(c + 1), (n - 1) * sizeof(T));
+ if ((n & 1) == 0)
+ tmp[n / 2].i = T0(0) * c[0];
+ for (size_t m = 1; 2 * m < n; ++m)
+ tmp[n - m].Set(tmp[m].r, -tmp[m].i);
+ fft<false>(tmp.data(), fct);
+ for (size_t m = 0; m < n; ++m)
+ c[m] = tmp[m].r;
+ }
+ }
+ };
+
+ //
+ // flexible (FFTPACK/Bluestein) complex 1D transform
+ //
+
+ template <typename T0>
+ class pocketfft_c
+ {
+ private:
+ std::unique_ptr<cfftp<T0>> packplan;
+ std::unique_ptr<fftblue<T0>> blueplan;
+ size_t len;
+
+ public:
+ POCKETFFT_NOINLINE pocketfft_c(size_t length) : len(length)
+ {
+ if (length == 0)
+ throw std::runtime_error("zero-length FFT requested");
+ size_t tmp = (length < 50) ? 0 : util::largest_prime_factor(length);
+ if (tmp * tmp <= length) {
+ packplan = std::unique_ptr<cfftp<T0>>(new cfftp<T0>(length));
+ return;
+ }
+ double comp1 = util::cost_guess(length);
+ double comp2 =
+ 2 * util::cost_guess(util::good_size_cmplx(2 * length - 1));
+ comp2 *= 1.5; /* fudge factor that appears to give good overall
+ performance */
+ if (comp2 < comp1) // use Bluestein
+ blueplan = std::unique_ptr<fftblue<T0>>(new fftblue<T0>(length));
+ else
+ packplan = std::unique_ptr<cfftp<T0>>(new cfftp<T0>(length));
+ }
+
+ template <typename T>
+ POCKETFFT_NOINLINE void exec(cmplx<T> c[], T0 fct, bool fwd) const
+ {
+ packplan ? packplan->exec(c, fct, fwd) : blueplan->exec(c, fct, fwd);
+ }
+
+ size_t length() const
+ {
+ return len;
+ }
+ };
+
+ //
+ // flexible (FFTPACK/Bluestein) real-valued 1D transform
+ //
+
+ template <typename T0>
+ class pocketfft_r
+ {
+ private:
+ std::unique_ptr<rfftp<T0>> packplan;
+ std::unique_ptr<fftblue<T0>> blueplan;
+ size_t len;
+
+ public:
+ POCKETFFT_NOINLINE pocketfft_r(size_t length) : len(length)
+ {
+ if (length == 0)
+ throw std::runtime_error("zero-length FFT requested");
+ size_t tmp = (length < 50) ? 0 : util::largest_prime_factor(length);
+ if (tmp * tmp <= length) {
+ packplan = std::unique_ptr<rfftp<T0>>(new rfftp<T0>(length));
+ return;
+ }
+ double comp1 = 0.5 * util::cost_guess(length);
+ double comp2 =
+ 2 * util::cost_guess(util::good_size_cmplx(2 * length - 1));
+ comp2 *= 1.5; /* fudge factor that appears to give good overall
+ performance */
+ if (comp2 < comp1) // use Bluestein
+ blueplan = std::unique_ptr<fftblue<T0>>(new fftblue<T0>(length));
+ else
+ packplan = std::unique_ptr<rfftp<T0>>(new rfftp<T0>(length));
+ }
+
+ template <typename T>
+ POCKETFFT_NOINLINE void exec(T c[], T0 fct, bool fwd) const
+ {
+ packplan ? packplan->exec(c, fct, fwd) : blueplan->exec_r(c, fct, fwd);
+ }
+
+ size_t length() const
+ {
+ return len;
+ }
+ };
+
+ //
+ // sine/cosine transforms
+ //
+
+ template <typename T0>
+ class T_dct1
+ {
+ private:
+ pocketfft_r<T0> fftplan;
+
+ public:
+ POCKETFFT_NOINLINE T_dct1(size_t length) : fftplan(2 * (length - 1))
+ {
+ }
+
+ template <typename T>
+ POCKETFFT_NOINLINE void exec(T c[], T0 fct, bool ortho, int /*type*/,
+ bool /*cosine*/) const
+ {
+ constexpr T0 sqrt2 = T0(1.414213562373095048801688724209698L);
+ size_t N = fftplan.length(), n = N / 2 + 1;
+ if (ortho) {
+ c[0] *= sqrt2;
+ c[n - 1] *= sqrt2;
+ }
+ arr<T> tmp(N);
+ tmp[0] = c[0];
+ for (size_t i = 1; i < n; ++i)
+ tmp[i] = tmp[N - i] = c[i];
+ fftplan.exec(tmp.data(), fct, true);
+ c[0] = tmp[0];
+ for (size_t i = 1; i < n; ++i)
+ c[i] = tmp[2 * i - 1];
+ if (ortho) {
+ c[0] *= sqrt2 * T0(0.5);
+ c[n - 1] *= sqrt2 * T0(0.5);
+ }
+ }
+
+ size_t length() const
+ {
+ return fftplan.length() / 2 + 1;
+ }
+ };
+
+ template <typename T0>
+ class T_dst1
+ {
+ private:
+ pocketfft_r<T0> fftplan;
+
+ public:
+ POCKETFFT_NOINLINE T_dst1(size_t length) : fftplan(2 * (length + 1))
+ {
+ }
+
+ template <typename T>
+ POCKETFFT_NOINLINE void exec(T c[], T0 fct, bool /*ortho*/, int /*type*/,
+ bool /*cosine*/) const
+ {
+ size_t N = fftplan.length(), n = N / 2 - 1;
+ arr<T> tmp(N);
+ tmp[0] = tmp[n + 1] = c[0] * 0;
+ for (size_t i = 0; i < n; ++i) {
+ tmp[i + 1] = c[i];
+ tmp[N - 1 - i] = -c[i];
+ }
+ fftplan.exec(tmp.data(), fct, true);
+ for (size_t i = 0; i < n; ++i)
+ c[i] = -tmp[2 * i + 2];
+ }
+
+ size_t length() const
+ {
+ return fftplan.length() / 2 - 1;
+ }
+ };
+
+ template <typename T0>
+ class T_dcst23
+ {
+ private:
+ pocketfft_r<T0> fftplan;
+ std::vector<T0> twiddle;
+
+ public:
+ POCKETFFT_NOINLINE T_dcst23(size_t length)
+ : fftplan(length), twiddle(length)
+ {
+ sincos_2pibyn<T0> tw(4 * length);
+ for (size_t i = 0; i < length; ++i)
+ twiddle[i] = tw[i + 1].r;
+ }
+
+ template <typename T>
+ POCKETFFT_NOINLINE void exec(T c[], T0 fct, bool ortho, int type,
+ bool cosine) const
+ {
+ constexpr T0 sqrt2 = T0(1.414213562373095048801688724209698L);
+ size_t N = length();
+ size_t NS2 = (N + 1) / 2;
+ if (type == 2) {
+ if (!cosine)
+ for (size_t k = 1; k < N; k += 2)
+ c[k] = -c[k];
+ c[0] *= 2;
+ if ((N & 1) == 0)
+ c[N - 1] *= 2;
+ for (size_t k = 1; k < N - 1; k += 2)
+ MPINPLACE(c[k + 1], c[k]);
+ fftplan.exec(c, fct, false);
+ for (size_t k = 1, kc = N - 1; k < NS2; ++k, --kc) {
+ T t1 = twiddle[k - 1] * c[kc] + twiddle[kc - 1] * c[k];
+ T t2 = twiddle[k - 1] * c[k] - twiddle[kc - 1] * c[kc];
+ c[k] = T0(0.5) * (t1 + t2);
+ c[kc] = T0(0.5) * (t1 - t2);
+ }
+ if ((N & 1) == 0)
+ c[NS2] *= twiddle[NS2 - 1];
+ if (!cosine)
+ for (size_t k = 0, kc = N - 1; k < kc; ++k, --kc)
+ std::swap(c[k], c[kc]);
+ if (ortho)
+ c[0] *= sqrt2 * T0(0.5);
+ } else {
+ if (ortho)
+ c[0] *= sqrt2;
+ if (!cosine)
+ for (size_t k = 0, kc = N - 1; k < NS2; ++k, --kc)
+ std::swap(c[k], c[kc]);
+ for (size_t k = 1, kc = N - 1; k < NS2; ++k, --kc) {
+ T t1 = c[k] + c[kc], t2 = c[k] - c[kc];
+ c[k] = twiddle[k - 1] * t2 + twiddle[kc - 1] * t1;
+ c[kc] = twiddle[k - 1] * t1 - twiddle[kc - 1] * t2;
+ }
+ if ((N & 1) == 0)
+ c[NS2] *= 2 * twiddle[NS2 - 1];
+ fftplan.exec(c, fct, true);
+ for (size_t k = 1; k < N - 1; k += 2)
+ MPINPLACE(c[k], c[k + 1]);
+ if (!cosine)
+ for (size_t k = 1; k < N; k += 2)
+ c[k] = -c[k];
+ }
+ }
+
+ size_t length() const
+ {
+ return fftplan.length();
+ }
+ };
+
+ template <typename T0>
+ class T_dcst4
+ {
+ private:
+ size_t N;
+ std::unique_ptr<pocketfft_c<T0>> fft;
+ std::unique_ptr<pocketfft_r<T0>> rfft;
+ arr<cmplx<T0>> C2;
+
+ public:
+ POCKETFFT_NOINLINE T_dcst4(size_t length)
+ : N(length), fft((N & 1) ? nullptr : new pocketfft_c<T0>(N / 2)),
+ rfft((N & 1) ? new pocketfft_r<T0>(N) : nullptr),
+ C2((N & 1) ? 0 : N / 2)
+ {
+ if ((N & 1) == 0) {
+ sincos_2pibyn<T0> tw(16 * N);
+ for (size_t i = 0; i < N / 2; ++i)
+ C2[i] = conj(tw[8 * i + 1]);
+ }
+ }
+
+ template <typename T>
+ POCKETFFT_NOINLINE void exec(T c[], T0 fct, bool /*ortho*/, int /*type*/,
+ bool cosine) const
+ {
+ size_t n2 = N / 2;
+ if (!cosine)
+ for (size_t k = 0, kc = N - 1; k < n2; ++k, --kc)
+ std::swap(c[k], c[kc]);
+ if (N & 1) {
+ // The following code is derived from the FFTW3 function apply_re11()
+ // and is released under the 3-clause BSD license with friendly
+ // permission of Matteo Frigo and Steven G. Johnson.
+
+ arr<T> y(N);
+ {
+ size_t i = 0, m = n2;
+ for (; m < N; ++i, m += 4)
+ y[i] = c[m];
+ for (; m < 2 * N; ++i, m += 4)
+ y[i] = -c[2 * N - m - 1];
+ for (; m < 3 * N; ++i, m += 4)
+ y[i] = -c[m - 2 * N];
+ for (; m < 4 * N; ++i, m += 4)
+ y[i] = c[4 * N - m - 1];
+ for (; i < N; ++i, m += 4)
+ y[i] = c[m - 4 * N];
+ }
+ rfft->exec(y.data(), fct, true);
+ {
+ auto SGN = [](size_t i) {
+ constexpr T0 sqrt2 = T0(1.414213562373095048801688724209698L);
+ return (i & 2) ? -sqrt2 : sqrt2;
+ };
+ c[n2] = y[0] * SGN(n2 + 1);
+ size_t i = 0, i1 = 1, k = 1;
+ for (; k < n2; ++i, ++i1, k += 2) {
+ c[i] = y[2 * k - 1] * SGN(i1) + y[2 * k] * SGN(i);
+ c[N - i1] = y[2 * k - 1] * SGN(N - i) - y[2 * k] * SGN(N - i1);
+ c[n2 - i1] =
+ y[2 * k + 1] * SGN(n2 - i) - y[2 * k + 2] * SGN(n2 - i1);
+ c[n2 + i1] =
+ y[2 * k + 1] * SGN(n2 + i + 2) + y[2 * k + 2] * SGN(n2 + i1);
+ }
+ if (k == n2) {
+ c[i] = y[2 * k - 1] * SGN(i + 1) + y[2 * k] * SGN(i);
+ c[N - i1] = y[2 * k - 1] * SGN(i + 2) + y[2 * k] * SGN(i1);
+ }
+ }
+
+ // FFTW-derived code ends here
+ } else {
+ // even length algorithm from
+ // https://www.appletonaudio.com/blog/2013/derivation-of-fast-dct-4-algorithm-based-on-dft/
+ arr<cmplx<T>> y(n2);
+ for (size_t i = 0; i < n2; ++i) {
+ y[i].Set(c[2 * i], c[N - 1 - 2 * i]);
+ y[i] *= C2[i];
+ }
+ fft->exec(y.data(), fct, true);
+ for (size_t i = 0, ic = n2 - 1; i < n2; ++i, --ic) {
+ c[2 * i] = 2 * (y[i].r * C2[i].r - y[i].i * C2[i].i);
+ c[2 * i + 1] = -2 * (y[ic].i * C2[ic].r + y[ic].r * C2[ic].i);
+ }
+ }
+ if (!cosine)
+ for (size_t k = 1; k < N; k += 2)
+ c[k] = -c[k];
+ }
+
+ size_t length() const
+ {
+ return N;
+ }
+ };
+
+ //
+ // multi-D infrastructure
+ //
+
+ template <typename T>
+ std::shared_ptr<T> get_plan(size_t length)
+ {
+#if POCKETFFT_CACHE_SIZE == 0
+ return std::make_shared<T>(length);
+#else
+ constexpr size_t nmax = POCKETFFT_CACHE_SIZE;
+ static std::array<std::shared_ptr<T>, nmax> cache;
+ static std::array<size_t, nmax> last_access{{0}};
+ static size_t access_counter = 0;
+ static std::mutex mut;
+
+ auto find_in_cache = [&]() -> std::shared_ptr<T> {
+ for (size_t i = 0; i < nmax; ++i)
+ if (cache[i] && (cache[i]->length() == length)) {
+ // no need to update if this is already the most recent entry
+ if (last_access[i] != access_counter) {
+ last_access[i] = ++access_counter;
+ // Guard against overflow
+ if (access_counter == 0)
+ last_access.fill(0);
+ }
+ return cache[i];
+ }
+
+ return nullptr;
+ };
+
+ {
+ std::lock_guard<std::mutex> lock(mut);
+ auto p = find_in_cache();
+ if (p)
+ return p;
+ }
+ auto plan = std::make_shared<T>(length);
+ {
+ std::lock_guard<std::mutex> lock(mut);
+ auto p = find_in_cache();
+ if (p)
+ return p;
+
+ size_t lru = 0;
+ for (size_t i = 1; i < nmax; ++i)
+ if (last_access[i] < last_access[lru])
+ lru = i;
+
+ cache[lru] = plan;
+ last_access[lru] = ++access_counter;
+ }
+ return plan;
+#endif
+ }
+
+ class arr_info
+ {
+ protected:
+ shape_t shp;
+ stride_t str;
+
+ public:
+ arr_info(const shape_t &shape_, const stride_t &stride_)
+ : shp(shape_), str(stride_)
+ {
+ }
+ size_t ndim() const
+ {
+ return shp.size();
+ }
+ size_t size() const
+ {
+ return util::prod(shp);
+ }
+ const shape_t &shape() const
+ {
+ return shp;
+ }
+ size_t shape(size_t i) const
+ {
+ return shp[i];
+ }
+ const stride_t &stride() const
+ {
+ return str;
+ }
+ const ptrdiff_t &stride(size_t i) const
+ {
+ return str[i];
+ }
+ };
+
+ template <typename T>
+ class cndarr : public arr_info
+ {
+ protected:
+ const char *d;
+
+ public:
+ cndarr(const void *data_, const shape_t &shape_, const stride_t &stride_)
+ : arr_info(shape_, stride_), d(reinterpret_cast<const char *>(data_))
+ {
+ }
+ const T &operator[](ptrdiff_t ofs) const
+ {
+ return *reinterpret_cast<const T *>(d + ofs);
+ }
+ };
+
+ template <typename T>
+ class ndarr : public cndarr<T>
+ {
+ public:
+ ndarr(void *data_, const shape_t &shape_, const stride_t &stride_)
+ : cndarr<T>::cndarr(const_cast<const void *>(data_), shape_, stride_)
+ {
+ }
+ T &operator[](ptrdiff_t ofs)
+ {
+ return *reinterpret_cast<T *>(const_cast<char *>(cndarr<T>::d + ofs));
+ }
+ };
+
+ template <size_t N>
+ class multi_iter
+ {
+ private:
+ shape_t pos;
+ const arr_info &iarr, &oarr;
+ ptrdiff_t p_ii, p_i[N], str_i, p_oi, p_o[N], str_o;
+ size_t idim, rem;
+
+ void advance_i()
+ {
+ for (int i_ = int(pos.size()) - 1; i_ >= 0; --i_) {
+ auto i = size_t(i_);
+ if (i == idim)
+ continue;
+ p_ii += iarr.stride(i);
+ p_oi += oarr.stride(i);
+ if (++pos[i] < iarr.shape(i))
+ return;
+ pos[i] = 0;
+ p_ii -= ptrdiff_t(iarr.shape(i)) * iarr.stride(i);
+ p_oi -= ptrdiff_t(oarr.shape(i)) * oarr.stride(i);
+ }
+ }
+
+ public:
+ multi_iter(const arr_info &iarr_, const arr_info &oarr_, size_t idim_)
+ : pos(iarr_.ndim(), 0), iarr(iarr_), oarr(oarr_), p_ii(0),
+ str_i(iarr.stride(idim_)), p_oi(0), str_o(oarr.stride(idim_)),
+ idim(idim_), rem(iarr.size() / iarr.shape(idim))
+ {
+ auto nshares = threading::num_threads();
+ if (nshares == 1)
+ return;
+ if (nshares == 0)
+ throw std::runtime_error("can't run with zero threads");
+ auto myshare = threading::thread_id();
+ if (myshare >= nshares)
+ throw std::runtime_error("impossible share requested");
+ size_t nbase = rem / nshares;
+ size_t additional = rem % nshares;
+ size_t lo =
+ myshare * nbase + ((myshare < additional) ? myshare : additional);
+ size_t hi = lo + nbase + (myshare < additional);
+ size_t todo = hi - lo;
+
+ size_t chunk = rem;
+ for (size_t i = 0; i < pos.size(); ++i) {
+ if (i == idim)
+ continue;
+ chunk /= iarr.shape(i);
+ size_t n_advance = lo / chunk;
+ pos[i] += n_advance;
+ p_ii += ptrdiff_t(n_advance) * iarr.stride(i);
+ p_oi += ptrdiff_t(n_advance) * oarr.stride(i);
+ lo -= n_advance * chunk;
+ }
+ rem = todo;
+ }
+ void advance(size_t n)
+ {
+ if (rem < n)
+ throw std::runtime_error("underrun");
+ for (size_t i = 0; i < n; ++i) {
+ p_i[i] = p_ii;
+ p_o[i] = p_oi;
+ advance_i();
+ }
+ rem -= n;
+ }
+ ptrdiff_t iofs(size_t i) const
+ {
+ return p_i[0] + ptrdiff_t(i) * str_i;
+ }
+ ptrdiff_t iofs(size_t j, size_t i) const
+ {
+ return p_i[j] + ptrdiff_t(i) * str_i;
+ }
+ ptrdiff_t oofs(size_t i) const
+ {
+ return p_o[0] + ptrdiff_t(i) * str_o;
+ }
+ ptrdiff_t oofs(size_t j, size_t i) const
+ {
+ return p_o[j] + ptrdiff_t(i) * str_o;
+ }
+ size_t length_in() const
+ {
+ return iarr.shape(idim);
+ }
+ size_t length_out() const
+ {
+ return oarr.shape(idim);
+ }
+ ptrdiff_t stride_in() const
+ {
+ return str_i;
+ }
+ ptrdiff_t stride_out() const
+ {
+ return str_o;
+ }
+ size_t remaining() const
+ {
+ return rem;
+ }
+ };
+
+ class simple_iter
+ {
+ private:
+ shape_t pos;
+ const arr_info &arr;
+ ptrdiff_t p;
+ size_t rem;
+
+ public:
+ simple_iter(const arr_info &arr_)
+ : pos(arr_.ndim(), 0), arr(arr_), p(0), rem(arr_.size())
+ {
+ }
+ void advance()
+ {
+ --rem;
+ for (int i_ = int(pos.size()) - 1; i_ >= 0; --i_) {
+ auto i = size_t(i_);
+ p += arr.stride(i);
+ if (++pos[i] < arr.shape(i))
+ return;
+ pos[i] = 0;
+ p -= ptrdiff_t(arr.shape(i)) * arr.stride(i);
+ }
+ }
+ ptrdiff_t ofs() const
+ {
+ return p;
+ }
+ size_t remaining() const
+ {
+ return rem;
+ }
+ };
+
+ class rev_iter
+ {
+ private:
+ shape_t pos;
+ const arr_info &arr;
+ std::vector<char> rev_axis;
+ std::vector<char> rev_jump;
+ size_t last_axis, last_size;
+ shape_t shp;
+ ptrdiff_t p, rp;
+ size_t rem;
+
+ public:
+ rev_iter(const arr_info &arr_, const shape_t &axes)
+ : pos(arr_.ndim(), 0), arr(arr_), rev_axis(arr_.ndim(), 0),
+ rev_jump(arr_.ndim(), 1), p(0), rp(0)
+ {
+ for (auto ax : axes)
+ rev_axis[ax] = 1;
+ last_axis = axes.back();
+ last_size = arr.shape(last_axis) / 2 + 1;
+ shp = arr.shape();
+ shp[last_axis] = last_size;
+ rem = 1;
+ for (auto i : shp)
+ rem *= i;
+ }
+ void advance()
+ {
+ --rem;
+ for (int i_ = int(pos.size()) - 1; i_ >= 0; --i_) {
+ auto i = size_t(i_);
+ p += arr.stride(i);
+ if (!rev_axis[i])
+ rp += arr.stride(i);
+ else {
+ rp -= arr.stride(i);
+ if (rev_jump[i]) {
+ rp += ptrdiff_t(arr.shape(i)) * arr.stride(i);
+ rev_jump[i] = 0;
+ }
+ }
+ if (++pos[i] < shp[i])
+ return;
+ pos[i] = 0;
+ p -= ptrdiff_t(shp[i]) * arr.stride(i);
+ if (rev_axis[i]) {
+ rp -= ptrdiff_t(arr.shape(i) - shp[i]) * arr.stride(i);
+ rev_jump[i] = 1;
+ } else
+ rp -= ptrdiff_t(shp[i]) * arr.stride(i);
+ }
+ }
+ ptrdiff_t ofs() const
+ {
+ return p;
+ }
+ ptrdiff_t rev_ofs() const
+ {
+ return rp;
+ }
+ size_t remaining() const
+ {
+ return rem;
+ }
+ };
+
+ template <typename T>
+ struct VTYPE {
+ };
+ template <typename T>
+ using vtype_t = typename VTYPE<T>::type;
+
+#ifndef POCKETFFT_NO_VECTORS
+ template <>
+ struct VTYPE<float> {
+ using type = float
+ __attribute__((vector_size(VLEN<float>::val * sizeof(float))));
+ };
+ template <>
+ struct VTYPE<double> {
+ using type = double
+ __attribute__((vector_size(VLEN<double>::val * sizeof(double))));
+ };
+ template <>
+ struct VTYPE<long double> {
+ using type = long double
+ __attribute__((vector_size(VLEN<long double>::val *
+ sizeof(long double))));
+ };
+#endif
+
+ template <typename T>
+ arr<char> alloc_tmp(const shape_t &shape, size_t axsize, size_t elemsize)
+ {
+ auto othersize = util::prod(shape) / axsize;
+ auto tmpsize = axsize * ((othersize >= VLEN<T>::val) ? VLEN<T>::val : 1);
+ return arr<char>(tmpsize * elemsize);
+ }
+ template <typename T>
+ arr<char> alloc_tmp(const shape_t &shape, const shape_t &axes,
+ size_t elemsize)
+ {
+ size_t fullsize = util::prod(shape);
+ size_t tmpsize = 0;
+ for (size_t i = 0; i < axes.size(); ++i) {
+ auto axsize = shape[axes[i]];
+ auto othersize = fullsize / axsize;
+ auto sz = axsize * ((othersize >= VLEN<T>::val) ? VLEN<T>::val : 1);
+ if (sz > tmpsize)
+ tmpsize = sz;
+ }
+ return arr<char>(tmpsize * elemsize);
+ }
+
+ template <typename T, size_t vlen>
+ void copy_input(const multi_iter<vlen> &it, const cndarr<cmplx<T>> &src,
+ cmplx<vtype_t<T>> *POCKETFFT_RESTRICT dst)
+ {
+ for (size_t i = 0; i < it.length_in(); ++i)
+ for (size_t j = 0; j < vlen; ++j) {
+ dst[i].r[j] = src[it.iofs(j, i)].r;
+ dst[i].i[j] = src[it.iofs(j, i)].i;
+ }
+ }
+
+ template <typename T, size_t vlen>
+ void copy_input(const multi_iter<vlen> &it, const cndarr<T> &src,
+ vtype_t<T> *POCKETFFT_RESTRICT dst)
+ {
+ for (size_t i = 0; i < it.length_in(); ++i)
+ for (size_t j = 0; j < vlen; ++j)
+ dst[i][j] = src[it.iofs(j, i)];
+ }
+
+ template <typename T, size_t vlen>
+ void copy_input(const multi_iter<vlen> &it, const cndarr<T> &src,
+ T *POCKETFFT_RESTRICT dst)
+ {
+ if (dst == &src[it.iofs(0)])
+ return; // in-place
+ for (size_t i = 0; i < it.length_in(); ++i)
+ dst[i] = src[it.iofs(i)];
+ }
+
+ template <typename T, size_t vlen>
+ void copy_output(const multi_iter<vlen> &it,
+ const cmplx<vtype_t<T>> *POCKETFFT_RESTRICT src,
+ ndarr<cmplx<T>> &dst)
+ {
+ for (size_t i = 0; i < it.length_out(); ++i)
+ for (size_t j = 0; j < vlen; ++j)
+ dst[it.oofs(j, i)].Set(src[i].r[j], src[i].i[j]);
+ }
+
+ template <typename T, size_t vlen>
+ void copy_output(const multi_iter<vlen> &it,
+ const vtype_t<T> *POCKETFFT_RESTRICT src, ndarr<T> &dst)
+ {
+ for (size_t i = 0; i < it.length_out(); ++i)
+ for (size_t j = 0; j < vlen; ++j)
+ dst[it.oofs(j, i)] = src[i][j];
+ }
+
+ template <typename T, size_t vlen>
+ void copy_output(const multi_iter<vlen> &it,
+ const T *POCKETFFT_RESTRICT src, ndarr<T> &dst)
+ {
+ if (src == &dst[it.oofs(0)])
+ return; // in-place
+ for (size_t i = 0; i < it.length_out(); ++i)
+ dst[it.oofs(i)] = src[i];
+ }
+
+ template <typename T>
+ struct add_vec {
+ using type = vtype_t<T>;
+ };
+ template <typename T>
+ struct add_vec<cmplx<T>> {
+ using type = cmplx<vtype_t<T>>;
+ };
+ template <typename T>
+ using add_vec_t = typename add_vec<T>::type;
+
+ template <typename Tplan, typename T, typename T0, typename Exec>
+ POCKETFFT_NOINLINE void general_nd(const cndarr<T> &in, ndarr<T> &out,
+ const shape_t &axes, T0 fct,
+ size_t nthreads, const Exec &exec,
+ const bool allow_inplace = true)
+ {
+ std::shared_ptr<Tplan> plan;
+
+ for (size_t iax = 0; iax < axes.size(); ++iax) {
+ size_t len = in.shape(axes[iax]);
+ if ((!plan) || (len != plan->length()))
+ plan = get_plan<Tplan>(len);
+
+ threading::thread_map(
+ util::thread_count(nthreads, in.shape(), axes[iax], VLEN<T>::val),
+ [&] {
+ constexpr auto vlen = VLEN<T0>::val;
+ auto storage = alloc_tmp<T0>(in.shape(), len, sizeof(T));
+ const auto &tin(iax == 0 ? in : out);
+ multi_iter<vlen> it(tin, out, axes[iax]);
+#ifndef POCKETFFT_NO_VECTORS
+ if (vlen > 1)
+ while (it.remaining() >= vlen) {
+ it.advance(vlen);
+ auto tdatav =
+ reinterpret_cast<add_vec_t<T> *>(storage.data());
+ exec(it, tin, out, tdatav, *plan, fct);
+ }
+#endif
+ while (it.remaining() > 0) {
+ it.advance(1);
+ auto buf = allow_inplace && it.stride_out() == sizeof(T)
+ ? &out[it.oofs(0)]
+ : reinterpret_cast<T *>(storage.data());
+ exec(it, tin, out, buf, *plan, fct);
+ }
+ }); // end of parallel region
+ fct = T0(1); // factor has been applied, use 1 for remaining axes
+ }
+ }
+
+ struct ExecC2C {
+ bool forward;
+
+ template <typename T0, typename T, size_t vlen>
+ void operator()(const multi_iter<vlen> &it, const cndarr<cmplx<T0>> &in,
+ ndarr<cmplx<T0>> &out, T *buf,
+ const pocketfft_c<T0> &plan, T0 fct) const
+ {
+ copy_input(it, in, buf);
+ plan.exec(buf, fct, forward);
+ copy_output(it, buf, out);
+ }
+ };
+
+ template <typename T, size_t vlen>
+ void copy_hartley(const multi_iter<vlen> &it,
+ const vtype_t<T> *POCKETFFT_RESTRICT src, ndarr<T> &dst)
+ {
+ for (size_t j = 0; j < vlen; ++j)
+ dst[it.oofs(j, 0)] = src[0][j];
+ size_t i = 1, i1 = 1, i2 = it.length_out() - 1;
+ for (i = 1; i < it.length_out() - 1; i += 2, ++i1, --i2)
+ for (size_t j = 0; j < vlen; ++j) {
+ dst[it.oofs(j, i1)] = src[i][j] + src[i + 1][j];
+ dst[it.oofs(j, i2)] = src[i][j] - src[i + 1][j];
+ }
+ if (i < it.length_out())
+ for (size_t j = 0; j < vlen; ++j)
+ dst[it.oofs(j, i1)] = src[i][j];
+ }
+
+ template <typename T, size_t vlen>
+ void copy_hartley(const multi_iter<vlen> &it,
+ const T *POCKETFFT_RESTRICT src, ndarr<T> &dst)
+ {
+ dst[it.oofs(0)] = src[0];
+ size_t i = 1, i1 = 1, i2 = it.length_out() - 1;
+ for (i = 1; i < it.length_out() - 1; i += 2, ++i1, --i2) {
+ dst[it.oofs(i1)] = src[i] + src[i + 1];
+ dst[it.oofs(i2)] = src[i] - src[i + 1];
+ }
+ if (i < it.length_out())
+ dst[it.oofs(i1)] = src[i];
+ }
+
+ struct ExecHartley {
+ template <typename T0, typename T, size_t vlen>
+ void operator()(const multi_iter<vlen> &it, const cndarr<T0> &in,
+ ndarr<T0> &out, T *buf, const pocketfft_r<T0> &plan,
+ T0 fct) const
+ {
+ copy_input(it, in, buf);
+ plan.exec(buf, fct, true);
+ copy_hartley(it, buf, out);
+ }
+ };
+
+ struct ExecDcst {
+ bool ortho;
+ int type;
+ bool cosine;
+
+ template <typename T0, typename T, typename Tplan, size_t vlen>
+ void operator()(const multi_iter<vlen> &it, const cndarr<T0> &in,
+ ndarr<T0> &out, T *buf, const Tplan &plan, T0 fct) const
+ {
+ copy_input(it, in, buf);
+ plan.exec(buf, fct, ortho, type, cosine);
+ copy_output(it, buf, out);
+ }
+ };
+
+ template <typename T>
+ POCKETFFT_NOINLINE void general_r2c(const cndarr<T> &in,
+ ndarr<cmplx<T>> &out, size_t axis,
+ bool forward, T fct, size_t nthreads)
+ {
+ auto plan = get_plan<pocketfft_r<T>>(in.shape(axis));
+ size_t len = in.shape(axis);
+ threading::thread_map(
+ util::thread_count(nthreads, in.shape(), axis, VLEN<T>::val), [&] {
+ constexpr auto vlen = VLEN<T>::val;
+ auto storage = alloc_tmp<T>(in.shape(), len, sizeof(T));
+ multi_iter<vlen> it(in, out, axis);
+#ifndef POCKETFFT_NO_VECTORS
+ if (vlen > 1)
+ while (it.remaining() >= vlen) {
+ it.advance(vlen);
+ auto tdatav = reinterpret_cast<vtype_t<T> *>(storage.data());
+ copy_input(it, in, tdatav);
+ plan->exec(tdatav, fct, true);
+ for (size_t j = 0; j < vlen; ++j)
+ out[it.oofs(j, 0)].Set(tdatav[0][j]);
+ size_t i = 1, ii = 1;
+ if (forward)
+ for (; i < len - 1; i += 2, ++ii)
+ for (size_t j = 0; j < vlen; ++j)
+ out[it.oofs(j, ii)].Set(tdatav[i][j], tdatav[i + 1][j]);
+ else
+ for (; i < len - 1; i += 2, ++ii)
+ for (size_t j = 0; j < vlen; ++j)
+ out[it.oofs(j, ii)].Set(tdatav[i][j], -tdatav[i + 1][j]);
+ if (i < len)
+ for (size_t j = 0; j < vlen; ++j)
+ out[it.oofs(j, ii)].Set(tdatav[i][j]);
+ }
+#endif
+ while (it.remaining() > 0) {
+ it.advance(1);
+ auto tdata = reinterpret_cast<T *>(storage.data());
+ copy_input(it, in, tdata);
+ plan->exec(tdata, fct, true);
+ out[it.oofs(0)].Set(tdata[0]);
+ size_t i = 1, ii = 1;
+ if (forward)
+ for (; i < len - 1; i += 2, ++ii)
+ out[it.oofs(ii)].Set(tdata[i], tdata[i + 1]);
+ else
+ for (; i < len - 1; i += 2, ++ii)
+ out[it.oofs(ii)].Set(tdata[i], -tdata[i + 1]);
+ if (i < len)
+ out[it.oofs(ii)].Set(tdata[i]);
+ }
+ }); // end of parallel region
+ }
+ template <typename T>
+ POCKETFFT_NOINLINE void general_c2r(const cndarr<cmplx<T>> &in,
+ ndarr<T> &out, size_t axis,
+ bool forward, T fct, size_t nthreads)
+ {
+ auto plan = get_plan<pocketfft_r<T>>(out.shape(axis));
+ size_t len = out.shape(axis);
+ threading::thread_map(
+ util::thread_count(nthreads, in.shape(), axis, VLEN<T>::val), [&] {
+ constexpr auto vlen = VLEN<T>::val;
+ auto storage = alloc_tmp<T>(out.shape(), len, sizeof(T));
+ multi_iter<vlen> it(in, out, axis);
+#ifndef POCKETFFT_NO_VECTORS
+ if (vlen > 1)
+ while (it.remaining() >= vlen) {
+ it.advance(vlen);
+ auto tdatav = reinterpret_cast<vtype_t<T> *>(storage.data());
+ for (size_t j = 0; j < vlen; ++j)
+ tdatav[0][j] = in[it.iofs(j, 0)].r;
+ {
+ size_t i = 1, ii = 1;
+ if (forward)
+ for (; i < len - 1; i += 2, ++ii)
+ for (size_t j = 0; j < vlen; ++j) {
+ tdatav[i][j] = in[it.iofs(j, ii)].r;
+ tdatav[i + 1][j] = -in[it.iofs(j, ii)].i;
+ }
+ else
+ for (; i < len - 1; i += 2, ++ii)
+ for (size_t j = 0; j < vlen; ++j) {
+ tdatav[i][j] = in[it.iofs(j, ii)].r;
+ tdatav[i + 1][j] = in[it.iofs(j, ii)].i;
+ }
+ if (i < len)
+ for (size_t j = 0; j < vlen; ++j)
+ tdatav[i][j] = in[it.iofs(j, ii)].r;
+ }
+ plan->exec(tdatav, fct, false);
+ copy_output(it, tdatav, out);
+ }
+#endif
+ while (it.remaining() > 0) {
+ it.advance(1);
+ auto tdata = reinterpret_cast<T *>(storage.data());
+ tdata[0] = in[it.iofs(0)].r;
+ {
+ size_t i = 1, ii = 1;
+ if (forward)
+ for (; i < len - 1; i += 2, ++ii) {
+ tdata[i] = in[it.iofs(ii)].r;
+ tdata[i + 1] = -in[it.iofs(ii)].i;
+ }
+ else
+ for (; i < len - 1; i += 2, ++ii) {
+ tdata[i] = in[it.iofs(ii)].r;
+ tdata[i + 1] = in[it.iofs(ii)].i;
+ }
+ if (i < len)
+ tdata[i] = in[it.iofs(ii)].r;
+ }
+ plan->exec(tdata, fct, false);
+ copy_output(it, tdata, out);
+ }
+ }); // end of parallel region
+ }
+
+ struct ExecR2R {
+ bool r2c, forward;
+
+ template <typename T0, typename T, size_t vlen>
+ void operator()(const multi_iter<vlen> &it, const cndarr<T0> &in,
+ ndarr<T0> &out, T *buf, const pocketfft_r<T0> &plan,
+ T0 fct) const
+ {
+ copy_input(it, in, buf);
+ if ((!r2c) && forward)
+ for (size_t i = 2; i < it.length_out(); i += 2)
+ buf[i] = -buf[i];
+ plan.exec(buf, fct, forward);
+ if (r2c && (!forward))
+ for (size_t i = 2; i < it.length_out(); i += 2)
+ buf[i] = -buf[i];
+ copy_output(it, buf, out);
+ }
+ };
+
+ template <typename T>
+ void c2c(const shape_t &shape, const stride_t &stride_in,
+ const stride_t &stride_out, const shape_t &axes, bool forward,
+ const std::complex<T> *data_in, std::complex<T> *data_out, T fct,
+ size_t nthreads = 1)
+ {
+ if (util::prod(shape) == 0)
+ return;
+ util::sanity_check(shape, stride_in, stride_out, data_in == data_out,
+ axes);
+ cndarr<cmplx<T>> ain(data_in, shape, stride_in);
+ ndarr<cmplx<T>> aout(data_out, shape, stride_out);
+ general_nd<pocketfft_c<T>>(ain, aout, axes, fct, nthreads,
+ ExecC2C{forward});
+ }
+
+ template <typename T>
+ void dct(const shape_t &shape, const stride_t &stride_in,
+ const stride_t &stride_out, const shape_t &axes, int type,
+ const T *data_in, T *data_out, T fct, bool ortho,
+ size_t nthreads = 1)
+ {
+ if ((type < 1) || (type > 4))
+ throw std::invalid_argument("invalid DCT type");
+ if (util::prod(shape) == 0)
+ return;
+ util::sanity_check(shape, stride_in, stride_out, data_in == data_out,
+ axes);
+ cndarr<T> ain(data_in, shape, stride_in);
+ ndarr<T> aout(data_out, shape, stride_out);
+ const ExecDcst exec{ortho, type, true};
+ if (type == 1)
+ general_nd<T_dct1<T>>(ain, aout, axes, fct, nthreads, exec);
+ else if (type == 4)
+ general_nd<T_dcst4<T>>(ain, aout, axes, fct, nthreads, exec);
+ else
+ general_nd<T_dcst23<T>>(ain, aout, axes, fct, nthreads, exec);
+ }
+
+ template <typename T>
+ void dst(const shape_t &shape, const stride_t &stride_in,
+ const stride_t &stride_out, const shape_t &axes, int type,
+ const T *data_in, T *data_out, T fct, bool ortho,
+ size_t nthreads = 1)
+ {
+ if ((type < 1) || (type > 4))
+ throw std::invalid_argument("invalid DST type");
+ if (util::prod(shape) == 0)
+ return;
+ util::sanity_check(shape, stride_in, stride_out, data_in == data_out,
+ axes);
+ cndarr<T> ain(data_in, shape, stride_in);
+ ndarr<T> aout(data_out, shape, stride_out);
+ const ExecDcst exec{ortho, type, false};
+ if (type == 1)
+ general_nd<T_dst1<T>>(ain, aout, axes, fct, nthreads, exec);
+ else if (type == 4)
+ general_nd<T_dcst4<T>>(ain, aout, axes, fct, nthreads, exec);
+ else
+ general_nd<T_dcst23<T>>(ain, aout, axes, fct, nthreads, exec);
+ }
+
+ template <typename T>
+ void r2c(const shape_t &shape_in, const stride_t &stride_in,
+ const stride_t &stride_out, size_t axis, bool forward,
+ const T *data_in, std::complex<T> *data_out, T fct,
+ size_t nthreads = 1)
+ {
+ if (util::prod(shape_in) == 0)
+ return;
+ util::sanity_check(shape_in, stride_in, stride_out, false, axis);
+ cndarr<T> ain(data_in, shape_in, stride_in);
+ shape_t shape_out(shape_in);
+ shape_out[axis] = shape_in[axis] / 2 + 1;
+ ndarr<cmplx<T>> aout(data_out, shape_out, stride_out);
+ general_r2c(ain, aout, axis, forward, fct, nthreads);
+ }
+
+ template <typename T>
+ void r2c(const shape_t &shape_in, const stride_t &stride_in,
+ const stride_t &stride_out, const shape_t &axes, bool forward,
+ const T *data_in, std::complex<T> *data_out, T fct,
+ size_t nthreads = 1)
+ {
+ if (util::prod(shape_in) == 0)
+ return;
+ util::sanity_check(shape_in, stride_in, stride_out, false, axes);
+ r2c(shape_in, stride_in, stride_out, axes.back(), forward, data_in,
+ data_out, fct, nthreads);
+ if (axes.size() == 1)
+ return;
+
+ shape_t shape_out(shape_in);
+ shape_out[axes.back()] = shape_in[axes.back()] / 2 + 1;
+ auto newaxes = shape_t{axes.begin(), --axes.end()};
+ c2c(shape_out, stride_out, stride_out, newaxes, forward, data_out,
+ data_out, T(1), nthreads);
+ }
+
+ template <typename T>
+ void c2r(const shape_t &shape_out, const stride_t &stride_in,
+ const stride_t &stride_out, size_t axis, bool forward,
+ const std::complex<T> *data_in, T *data_out, T fct,
+ size_t nthreads = 1)
+ {
+ if (util::prod(shape_out) == 0)
+ return;
+ util::sanity_check(shape_out, stride_in, stride_out, false, axis);
+ shape_t shape_in(shape_out);
+ shape_in[axis] = shape_out[axis] / 2 + 1;
+ cndarr<cmplx<T>> ain(data_in, shape_in, stride_in);
+ ndarr<T> aout(data_out, shape_out, stride_out);
+ general_c2r(ain, aout, axis, forward, fct, nthreads);
+ }
+
+ template <typename T>
+ void c2r(const shape_t &shape_out, const stride_t &stride_in,
+ const stride_t &stride_out, const shape_t &axes, bool forward,
+ const std::complex<T> *data_in, T *data_out, T fct,
+ size_t nthreads = 1)
+ {
+ if (util::prod(shape_out) == 0)
+ return;
+ if (axes.size() == 1)
+ return c2r(shape_out, stride_in, stride_out, axes[0], forward, data_in,
+ data_out, fct, nthreads);
+ util::sanity_check(shape_out, stride_in, stride_out, false, axes);
+ auto shape_in = shape_out;
+ shape_in[axes.back()] = shape_out[axes.back()] / 2 + 1;
+ auto nval = util::prod(shape_in);
+ stride_t stride_inter(shape_in.size());
+ stride_inter.back() = sizeof(cmplx<T>);
+ for (int i = int(shape_in.size()) - 2; i >= 0; --i)
+ stride_inter[size_t(i)] =
+ stride_inter[size_t(i + 1)] * ptrdiff_t(shape_in[size_t(i + 1)]);
+ arr<std::complex<T>> tmp(nval);
+ auto newaxes = shape_t{axes.begin(), --axes.end()};
+ c2c(shape_in, stride_in, stride_inter, newaxes, forward, data_in,
+ tmp.data(), T(1), nthreads);
+ c2r(shape_out, stride_inter, stride_out, axes.back(), forward, tmp.data(),
+ data_out, fct, nthreads);
+ }
+
+ template <typename T>
+ void r2r_fftpack(const shape_t &shape, const stride_t &stride_in,
+ const stride_t &stride_out, const shape_t &axes,
+ bool real2hermitian, bool forward, const T *data_in,
+ T *data_out, T fct, size_t nthreads = 1)
+ {
+ if (util::prod(shape) == 0)
+ return;
+ util::sanity_check(shape, stride_in, stride_out, data_in == data_out,
+ axes);
+ cndarr<T> ain(data_in, shape, stride_in);
+ ndarr<T> aout(data_out, shape, stride_out);
+ general_nd<pocketfft_r<T>>(ain, aout, axes, fct, nthreads,
+ ExecR2R{real2hermitian, forward});
+ }
+
+ template <typename T>
+ void r2r_separable_hartley(const shape_t &shape, const stride_t &stride_in,
+ const stride_t &stride_out, const shape_t &axes,
+ const T *data_in, T *data_out, T fct,
+ size_t nthreads = 1)
+ {
+ if (util::prod(shape) == 0)
+ return;
+ util::sanity_check(shape, stride_in, stride_out, data_in == data_out,
+ axes);
+ cndarr<T> ain(data_in, shape, stride_in);
+ ndarr<T> aout(data_out, shape, stride_out);
+ general_nd<pocketfft_r<T>>(ain, aout, axes, fct, nthreads, ExecHartley{},
+ false);
+ }
+
+ template <typename T>
+ void r2r_genuine_hartley(const shape_t &shape, const stride_t &stride_in,
+ const stride_t &stride_out, const shape_t &axes,
+ const T *data_in, T *data_out, T fct,
+ size_t nthreads = 1)
+ {
+ if (util::prod(shape) == 0)
+ return;
+ if (axes.size() == 1)
+ return r2r_separable_hartley(shape, stride_in, stride_out, axes,
+ data_in, data_out, fct, nthreads);
+ util::sanity_check(shape, stride_in, stride_out, data_in == data_out,
+ axes);
+ shape_t tshp(shape);
+ tshp[axes.back()] = tshp[axes.back()] / 2 + 1;
+ arr<std::complex<T>> tdata(util::prod(tshp));
+ stride_t tstride(shape.size());
+ tstride.back() = sizeof(std::complex<T>);
+ for (size_t i = tstride.size() - 1; i > 0; --i)
+ tstride[i - 1] = tstride[i] * ptrdiff_t(tshp[i]);
+ r2c(shape, stride_in, tstride, axes, true, data_in, tdata.data(), fct,
+ nthreads);
+ cndarr<cmplx<T>> atmp(tdata.data(), tshp, tstride);
+ ndarr<T> aout(data_out, shape, stride_out);
+ simple_iter iin(atmp);
+ rev_iter iout(aout, axes);
+ while (iin.remaining() > 0) {
+ auto v = atmp[iin.ofs()];
+ aout[iout.ofs()] = v.r + v.i;
+ aout[iout.rev_ofs()] = v.r - v.i;
+ iin.advance();
+ iout.advance();
+ }
+ }
+
+ } // namespace detail
+
+ using detail::FORWARD;
+ using detail::BACKWARD;
+ using detail::shape_t;
+ using detail::stride_t;
+ using detail::c2c;
+ using detail::c2r;
+ using detail::r2c;
+ using detail::r2r_fftpack;
+ using detail::r2r_separable_hartley;
+ using detail::r2r_genuine_hartley;
+ using detail::dct;
+ using detail::dst;
+
+} // namespace pocketfft
+
+#undef POCKETFFT_NOINLINE
+#undef POCKETFFT_RESTRICT
+
+#endif // POCKETFFT_HDRONLY_H
+#endif // PYTHONIC_INCLUDE_NUMPY_FFT_POCKETFFT_HPP
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fft/rfft.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fft/rfft.hpp
new file mode 100644
index 00000000000..91e6fab8291
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fft/rfft.hpp
@@ -0,0 +1,106 @@
+#ifndef PYTHONIC_NUMPY_FFT_RFFT_HPP
+#define PYTHONIC_NUMPY_FFT_RFFT_HPP
+#include "pythonic/include/numpy/fft/rfft.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/include/utils/array_helper.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/numpy/fft/c2c.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace fft
+ {
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ rfft(types::ndarray<T, pS> const &in_array, types::none_type n, long axis,
+ types::str const &norm)
+ {
+ return r2c(in_array, -1, axis, norm, true, false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ rfft(types::ndarray<T, pS> const &in_array, types::none_type n, long axis,
+ types::none_type norm)
+ {
+ return r2c(in_array, -1, axis, "", true, false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ rfft(types::ndarray<T, pS> const &in_array, long n, long axis,
+ types::none_type norm)
+ {
+ return r2c(in_array, n, axis, "", true, false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_floating_point<T>::value,
+ std::complex<T>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ rfft(types::ndarray<T, pS> const &in_array, long n, long axis,
+ types::str const &norm)
+ {
+ return r2c(in_array, n, axis, norm, true, false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ rfft(types::ndarray<T, pS> const &in_array, types::none_type n, long axis,
+ types::str const &norm)
+ {
+ auto tmp_array = _copy_to_double(in_array);
+ return r2c(tmp_array, -1, axis, norm, true, false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ rfft(types::ndarray<T, pS> const &in_array, types::none_type n, long axis,
+ types::none_type norm)
+ {
+ auto tmp_array = _copy_to_double(in_array);
+ return r2c(tmp_array, -1, axis, "", true, false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ rfft(types::ndarray<T, pS> const &in_array, long n, long axis,
+ types::none_type norm)
+ {
+ auto tmp_array = _copy_to_double(in_array);
+ return r2c(tmp_array, n, axis, "", true, false);
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename std::enable_if<std::is_integral<T>::value,
+ std::complex<double>>::type,
+ types::array<long, std::tuple_size<pS>::value>>
+ rfft(types::ndarray<T, pS> const &in_array, long n, long axis,
+ types::str const &norm)
+ {
+ auto tmp_array = _copy_to_double(in_array);
+ return r2c(tmp_array, n, axis, norm, true, false);
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(rfft);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fill_diagonal.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fill_diagonal.hpp
new file mode 100644
index 00000000000..5be8b09d212
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fill_diagonal.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_NUMPY_FILL_DIAGONAL_HPP
+#define PYTHONIC_NUMPY_FILL_DIAGONAL_HPP
+
+#include "pythonic/include/numpy/fill_diagonal.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/NoneType.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ types::none_type fill_diagonal(E &&expr,
+ typename std::decay<E>::type::dtype fill_value)
+ {
+ constexpr auto N = std::decay<E>::type::value;
+ types::array<long, N> indices;
+ for (long i = 0, n = sutils::min(expr); i < n; ++i) {
+ std::fill(indices.begin(), indices.end(), i);
+ expr.fast(indices) = fill_value;
+ }
+ return {};
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/finfo.hpp b/contrib/python/pythran/pythran/pythonic/numpy/finfo.hpp
new file mode 100644
index 00000000000..cb9c2b10bab
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/finfo.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_NUMPY_FINFO_HPP
+#define PYTHONIC_NUMPY_FINFO_HPP
+
+#include "pythonic/include/numpy/finfo.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/finfo.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class dtype>
+ types::finfo<typename dtype::type> finfo(dtype d)
+ {
+ return types::finfo<typename dtype::type>();
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fix.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fix.hpp
new file mode 100644
index 00000000000..5b1b020dc29
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fix.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_NUMPY_FIX_HPP
+#define PYTHONIC_NUMPY_FIX_HPP
+
+#include "pythonic/include/numpy/fix.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME fix
+#define NUMPY_NARY_FUNC_SYM std::trunc
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/flatnonzero.hpp b/contrib/python/pythran/pythran/pythonic/numpy/flatnonzero.hpp
new file mode 100644
index 00000000000..221574cb59c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/flatnonzero.hpp
@@ -0,0 +1,44 @@
+#ifndef PYTHONIC_NUMPY_FLATNONZERO_HPP
+#define PYTHONIC_NUMPY_FLATNONZERO_HPP
+
+#include "pythonic/include/numpy/flatnonzero.hpp"
+
+#include "pythonic/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace
+ {
+ template <class I, class O>
+ void _flatnonzero(I begin, I end, O &out, long &i, utils::int_<1>)
+ {
+ for (; begin != end; ++begin, ++i)
+ if (*begin)
+ *out++ = i;
+ }
+
+ template <class I, class O, size_t N>
+ void _flatnonzero(I begin, I end, O &out, long &i, utils::int_<N>)
+ {
+ for (; begin != end; ++begin)
+ _flatnonzero((*begin).begin(), (*begin).end(), out, i,
+ utils::int_<N - 1>());
+ }
+ }
+ template <class E>
+ types::ndarray<long, types::pshape<long>> flatnonzero(E const &expr)
+ {
+ long n = expr.flat_size();
+ utils::shared_ref<types::raw_array<long>> buffer(n);
+ long *iter = buffer->data;
+ long i = 0;
+ _flatnonzero(expr.begin(), expr.end(), iter, i, utils::int_<E::value>());
+ types::pshape<long> shape = iter - buffer->data;
+ return types::ndarray<long, types::pshape<long>>(std::move(buffer), shape);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/flip.hpp b/contrib/python/pythran/pythran/pythonic/numpy/flip.hpp
new file mode 100644
index 00000000000..27241f061d9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/flip.hpp
@@ -0,0 +1,36 @@
+#ifndef PYTHONIC_NUMPY_FLIP_HPP
+#define PYTHONIC_NUMPY_FLIP_HPP
+
+#include "pythonic/include/numpy/flip.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_conversion.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace details
+ {
+ template <class E, class S, size_t... I>
+ auto flip(E const &expr, S const &slices, utils::index_sequence<I...>)
+ -> decltype(expr(slices[I]...))
+ {
+ return expr(slices[I]...);
+ }
+ }
+
+ template <class E>
+ auto flip(E const &expr, long axis)
+ -> decltype(details::flip(expr, std::array<types::slice, E::value>{},
+ utils::make_index_sequence<E::value>{}))
+ {
+ std::array<types::slice, E::value> slices;
+ slices[axis].step = -1;
+ return details::flip(expr, slices, utils::make_index_sequence<E::value>{});
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fliplr.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fliplr.hpp
new file mode 100644
index 00000000000..e7354ff2150
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fliplr.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_NUMPY_FLIPLR_HPP
+#define PYTHONIC_NUMPY_FLIPLR_HPP
+
+#include "pythonic/include/numpy/fliplr.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ auto fliplr(E &&expr) -> decltype(std::forward<E>(expr)(
+ types::cstride_slice<1>{builtins::None, builtins::None},
+ types::slice{builtins::None, builtins::None, -1}))
+ {
+ return std::forward<E>(expr)(
+ types::cstride_slice<1>{builtins::None, builtins::None},
+ types::slice{builtins::None, builtins::None, -1});
+ }
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/flipud.hpp b/contrib/python/pythran/pythran/pythonic/numpy/flipud.hpp
new file mode 100644
index 00000000000..3e2799dd945
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/flipud.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_NUMPY_FLIPUD_HPP
+#define PYTHONIC_NUMPY_FLIPUD_HPP
+
+#include "pythonic/include/numpy/flipud.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ auto flipud(E &&expr) -> decltype(
+ std::forward<E>(expr)[types::slice{builtins::None, builtins::None, -1}])
+ {
+ return std::forward<E>(
+ expr)[types::slice{builtins::None, builtins::None, -1}];
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/float128.hpp b/contrib/python/pythran/pythran/pythonic/numpy/float128.hpp
new file mode 100644
index 00000000000..d8e678d3fcd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/float128.hpp
@@ -0,0 +1,36 @@
+#ifndef PYTHONIC_NUMPY_FLOAT128_HPP
+#define PYTHONIC_NUMPY_FLOAT128_HPP
+
+#include "pythonic/include/numpy/float128.hpp"
+
+#include "pythonic/types/numpy_op_helper.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/meta.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace details
+ {
+
+ inline long double float128()
+ {
+ return {};
+ }
+
+ template <class V>
+ long double float128(V v)
+ {
+ return static_cast<long double>(v);
+ }
+ } // namespace details
+
+#define NUMPY_NARY_FUNC_NAME float128
+#define NUMPY_NARY_FUNC_SYM details::float128
+#include "pythonic/types/numpy_nary_expr.hpp"
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/float_.hpp b/contrib/python/pythran/pythran/pythonic/numpy/float_.hpp
new file mode 100644
index 00000000000..356ae7d1a84
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/float_.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_NUMPY_FLOAT_HPP
+#define PYTHONIC_NUMPY_FLOAT_HPP
+
+#include "pythonic/include/numpy/float_.hpp"
+#include "pythonic/include/numpy/float64.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME float_
+#define NUMPY_NARY_FUNC_SYM details::float64
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/floor_divide/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/floor_divide/accumulate.hpp
new file mode 100644
index 00000000000..0fbefbb37f7
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/floor_divide/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_FLOOR_DIVIDE_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_FLOOR_DIVIDE_ACCUMULATE_HPP
+
+#define UFUNC_NAME floor_divide
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fmax.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fmax.hpp
new file mode 100644
index 00000000000..044a426fef6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fmax.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_FMAX_HPP
+#define PYTHONIC_NUMPY_FMAX_HPP
+
+#include "pythonic/include/numpy/fmin.hpp"
+#include "pythonic/numpy/maximum.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fmax/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fmax/accumulate.hpp
new file mode 100644
index 00000000000..e43fa9814ab
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fmax/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_FMAX_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_FMAX_ACCUMULATE_HPP
+
+#define UFUNC_NAME fmax
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fmax/reduce.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fmax/reduce.hpp
new file mode 100644
index 00000000000..a2e7b0e354b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fmax/reduce.hpp
@@ -0,0 +1,11 @@
+#ifndef PYTHONIC_NUMPY_FMAX_REDUCE_HPP
+#define PYTHONIC_NUMPY_FMAX_REDUCE_HPP
+
+#define UFUNC_NAME fmax
+#define UFUNC_INAME imax
+#include "pythonic/include/numpy/fmax/reduce.hpp"
+#include "pythonic/numpy/ufunc_reduce.hpp"
+#undef UFUNC_NAME
+#undef UFUNC_INAME
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fmin.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fmin.hpp
new file mode 100644
index 00000000000..9edaffd5364
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fmin.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_FMIN_HPP
+#define PYTHONIC_NUMPY_FMIN_HPP
+
+#include "pythonic/include/numpy/fmin.hpp"
+#include "pythonic/numpy/minimum.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fmin/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fmin/accumulate.hpp
new file mode 100644
index 00000000000..0b325014c16
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fmin/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_FMIN_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_FMIN_ACCUMULATE_HPP
+
+#define UFUNC_NAME fmin
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fmin/reduce.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fmin/reduce.hpp
new file mode 100644
index 00000000000..a4d1c6e6d90
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fmin/reduce.hpp
@@ -0,0 +1,11 @@
+#ifndef PYTHONIC_NUMPY_FMIN_REDUCE_HPP
+#define PYTHONIC_NUMPY_FMIN_REDUCE_HPP
+
+#define UFUNC_NAME fmin
+#define UFUNC_INAME imin
+#include "pythonic/include/numpy/fmin/reduce.hpp"
+#include "pythonic/numpy/ufunc_reduce.hpp"
+#undef UFUNC_NAME
+#undef UFUNC_INAME
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fmod.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fmod.hpp
new file mode 100644
index 00000000000..cfb9ecc66cc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fmod.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_NUMPY_FMOD_HPP
+#define PYTHONIC_NUMPY_FMOD_HPP
+
+#include "pythonic/include/numpy/fmod.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME fmod
+#define NUMPY_NARY_FUNC_SYM xsimd::fmod
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fmod/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fmod/accumulate.hpp
new file mode 100644
index 00000000000..abbeb190a0e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fmod/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_FMOD_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_FMOD_ACCUMULATE_HPP
+
+#define UFUNC_NAME fmod
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/frexp.hpp b/contrib/python/pythran/pythran/pythonic/numpy/frexp.hpp
new file mode 100644
index 00000000000..1d9bc102436
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/frexp.hpp
@@ -0,0 +1,62 @@
+#ifndef PYTHONIC_NUMPY_FREXP_HPP
+#define PYTHONIC_NUMPY_FREXP_HPP
+
+#include "pythonic/include/numpy/frexp.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_conversion.hpp"
+#include "pythonic/types/traits.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T>
+ typename std::enable_if<std::is_scalar<T>::value, std::tuple<T, int>>::type
+ frexp(T val)
+ {
+ int exp;
+ T significand = std::frexp(val, &exp);
+ return std::make_tuple(significand, exp);
+ }
+
+ namespace
+ {
+ template <class E, class F, class G>
+ void _frexp(E begin, E end, F significands_iter, G exps_iter,
+ utils::int_<1>)
+ {
+ for (; begin != end; ++begin, ++significands_iter, ++exps_iter)
+ *significands_iter = std::frexp(*begin, exps_iter);
+ }
+
+ template <class E, class F, class G, size_t N>
+ void _frexp(E begin, E end, F significands_iter, G exps_iter,
+ utils::int_<N>)
+ {
+ for (; begin != end; ++begin, ++significands_iter, ++exps_iter)
+ _frexp((*begin).begin(), (*begin).end(), (*significands_iter).begin(),
+ (*exps_iter).begin(), utils::int_<N - 1>());
+ }
+ }
+
+ template <class E>
+ typename std::enable_if<
+ !types::is_dtype<E>::value,
+ std::tuple<types::ndarray<typename E::dtype, typename E::shape_t>,
+ types::ndarray<int, typename E::shape_t>>>::type
+ frexp(E const &arr)
+ {
+ auto arr_shape = sutils::getshape(arr);
+ types::ndarray<typename E::dtype, typename E::shape_t> significands(
+ arr_shape, builtins::None);
+ types::ndarray<int, typename E::shape_t> exps(arr_shape, builtins::None);
+ _frexp(arr.begin(), arr.end(), significands.begin(), exps.begin(),
+ utils::int_<E::value>());
+ return std::make_tuple(significands, exps);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fromfile.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fromfile.hpp
new file mode 100644
index 00000000000..ea8c4aa7cec
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fromfile.hpp
@@ -0,0 +1,51 @@
+#ifndef PYTHONIC_NUMPY_FROMFILE_HPP
+#define PYTHONIC_NUMPY_FROMFILE_HPP
+
+#include "pythonic/include/numpy/fromfile.hpp"
+
+#include "pythonic/builtins/FileNotFoundError.hpp"
+#include "pythonic/builtins/NotImplementedError.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+#include <fstream>
+
+#include <limits>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class dtype>
+ types::ndarray<typename dtype::type, types::pshape<long>>
+ fromfile(types::str const &file_name, dtype d, long count,
+ types::str const &sep, long offset)
+ {
+ if (sep.size() != 0)
+ throw types::NotImplementedError(
+ "Sep input is not implemented yet, should be left empty");
+ std::fstream fs;
+ fs.open(file_name.c_str(), std::fstream::in | std::fstream::binary);
+ if (fs.rdstate() != std::fstream::goodbit) {
+ throw types::FileNotFoundError("Could not find file " + file_name);
+ }
+ fs.seekp(offset, std::fstream::beg);
+ auto n1 = fs.tellp();
+ fs.seekp(0, std::fstream::end);
+ long maxCount = (fs.tellp() - n1) / sizeof(typename dtype::type);
+ fs.seekp(offset, std::fstream::beg);
+ if (count < 0) {
+ count = maxCount;
+ } else if (count > maxCount) {
+ count = maxCount;
+ }
+
+ types::ndarray<typename dtype::type, types::pshape<long>> res(
+ types::pshape<long>{count}, types::none_type{});
+ fs.read((char *)res.buffer, sizeof(typename dtype::type) * count);
+ return res;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fromfunction.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fromfunction.hpp
new file mode 100644
index 00000000000..1d60afb6478
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fromfunction.hpp
@@ -0,0 +1,69 @@
+#ifndef PYTHONIC_NUMPY_FROMFUNCTION_HPP
+#define PYTHONIC_NUMPY_FROMFUNCTION_HPP
+
+#include "pythonic/include/numpy/fromfunction.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/utils/tags.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class F, size_t N, class dtype, class Tags>
+ struct fromfunction_helper;
+
+ template <class F, class dtype, class purity_tag>
+ template <class pS>
+ types::ndarray<typename std::remove_cv<typename std::remove_reference<
+ typename std::result_of<F(dtype)>::type>::type>::type,
+ pS> fromfunction_helper<F, 1, dtype, purity_tag>::
+ operator()(F &&f, pS const &shape, dtype d)
+ {
+ types::ndarray<typename std::remove_cv<typename std::remove_reference<
+ typename std::result_of<F(dtype)>::type>::type>::type,
+ pS> out(shape, builtins::None);
+ long n = out.template shape<0>();
+ for (long i = 0; i < n; ++i)
+ out[i] = f(i);
+ return out;
+ }
+
+ template <class F, class dtype, class purity_tag>
+ template <class pS>
+ types::ndarray<
+ typename std::remove_cv<typename std::remove_reference<
+ typename std::result_of<F(dtype, dtype)>::type>::type>::type,
+ pS> fromfunction_helper<F, 2, dtype, purity_tag>::
+ operator()(F &&f, pS const &shape, dtype d)
+ {
+ types::ndarray<
+ typename std::remove_cv<typename std::remove_reference<
+ typename std::result_of<F(dtype, dtype)>::type>::type>::type,
+ pS> out(shape, builtins::None);
+ long n = out.template shape<0>();
+ long m = out.template shape<1>();
+ for (long i = 0; i < n; ++i)
+ for (long j = 0; j < m; ++j)
+ out[i][j] = f(i, j);
+ return out;
+ }
+
+ template <class F, class pS, class dtype>
+ auto fromfunction(F &&f, pS const &shape, dtype d)
+ -> decltype(fromfunction_helper<F, std::tuple_size<pS>::value, dtype,
+ typename pythonic::purity_of<F>::type>()(
+ std::forward<F>(f), shape))
+ {
+ return fromfunction_helper<F, std::tuple_size<pS>::value, dtype,
+ typename pythonic::purity_of<F>::type>()(
+ std::forward<F>(f), shape);
+ }
+
+ /* TODO: must specialize for higher order */
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fromiter.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fromiter.hpp
new file mode 100644
index 00000000000..f2b31e6f1e9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fromiter.hpp
@@ -0,0 +1,35 @@
+#ifndef PYTHONIC_NUMPY_FROMITER_HPP
+#define PYTHONIC_NUMPY_FROMITER_HPP
+
+#include "pythonic/include/numpy/fromiter.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class Iterable, class dtype>
+ types::ndarray<typename std::remove_cv<typename std::remove_reference<
+ Iterable>::type>::type::value_type,
+ types::pshape<long>>
+ fromiter(Iterable &&iterable, dtype d, long count)
+ {
+ using T = typename std::remove_cv<
+ typename std::remove_reference<Iterable>::type>::type::value_type;
+ if (count < 0) {
+ types::list<T> buffer(0);
+ std::copy(iterable.begin(), iterable.end(), std::back_inserter(buffer));
+ return {buffer};
+ } else {
+ utils::shared_ref<types::raw_array<T>> buffer(count);
+ std::copy_n(iterable.begin(), count, buffer->data);
+ types::array<long, 1> shape = {count};
+ return {buffer, shape};
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/fromstring.hpp b/contrib/python/pythran/pythran/pythonic/numpy/fromstring.hpp
new file mode 100644
index 00000000000..c7e548bff5b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/fromstring.hpp
@@ -0,0 +1,56 @@
+#ifndef PYTHONIC_NUMPY_FROMSTRING_HPP
+#define PYTHONIC_NUMPY_FROMSTRING_HPP
+
+#include "pythonic/include/numpy/fromstring.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/list.hpp"
+#include "pythonic/types/str.hpp"
+
+#include <limits>
+#include <sstream>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class dtype>
+ types::ndarray<typename dtype::type, types::pshape<long>>
+ fromstring(types::str const &string, dtype d, long count,
+ types::str const &sep)
+ {
+ if (sep) {
+ types::list<typename dtype::type> res(0);
+ if (count < 0)
+ count = std::numeric_limits<long>::max();
+ else
+ res.reserve(count);
+ size_t current;
+ size_t next = -1;
+ long numsplit = 0;
+ do {
+ current = next + 1;
+ next = string.find_first_of(sep, current);
+ typename dtype::type item;
+ std::istringstream iss(string.substr(current, next - current).chars());
+ iss >> item;
+ res.push_back(item);
+ } while (next != types::str::npos && ++numsplit < count);
+ return {res};
+ } else {
+ if (count < 0)
+ count = string.size();
+ types::pshape<long> shape = count;
+ utils::shared_ref<types::raw_array<typename dtype::type>> buffer(
+ std::get<0>(shape));
+ auto const *tstring =
+ reinterpret_cast<typename dtype::type const *>(string.c_str());
+ std::copy(tstring, tstring + std::get<0>(shape), buffer->data);
+ return {buffer, shape};
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/full.hpp b/contrib/python/pythran/pythran/pythonic/numpy/full.hpp
new file mode 100644
index 00000000000..9153abd8716
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/full.hpp
@@ -0,0 +1,61 @@
+#ifndef PYTHONIC_NUMPY_FULL_HPP
+#define PYTHONIC_NUMPY_FULL_HPP
+
+#include "pythonic/include/numpy/full.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class pS, class F, class dtype>
+ types::ndarray<typename dtype::type, sutils::shape_t<pS>>
+ full(pS const &shape, F fill_value, dtype d)
+ {
+ return {(sutils::shape_t<pS>)shape, typename dtype::type(fill_value)};
+ }
+
+ template <class F, class dtype>
+ types::ndarray<typename dtype::type, types::pshape<long>>
+ full(long size, F fill_value, dtype d)
+ {
+ return full(types::pshape<long>(size), fill_value, d);
+ }
+
+ template <long N, class F, class dtype>
+ types::ndarray<typename dtype::type,
+ types::pshape<std::integral_constant<long, N>>>
+ full(std::integral_constant<long, N>, F fill_value, dtype d)
+ {
+ return full(types::pshape<std::integral_constant<long, N>>({}), fill_value,
+ d);
+ }
+
+ template <class pS, class F>
+ types::ndarray<F, sutils::shape_t<pS>> full(pS const &shape, F fill_value,
+ types::none_type)
+ {
+ return {(sutils::shape_t<pS>)shape, fill_value};
+ }
+
+ template <class F>
+ types::ndarray<F, types::pshape<long>> full(long size, F fill_value,
+ types::none_type nt)
+ {
+ return full(types::pshape<long>(size), fill_value, nt);
+ }
+
+ template <long N, class F>
+ types::ndarray<F, types::pshape<std::integral_constant<long, N>>>
+ full(std::integral_constant<long, N>, F fill_value, types::none_type nt)
+ {
+ return full(types::pshape<std::integral_constant<long, N>>({}), fill_value,
+ nt);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/full_like.hpp b/contrib/python/pythran/pythran/pythonic/numpy/full_like.hpp
new file mode 100644
index 00000000000..75421404f52
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/full_like.hpp
@@ -0,0 +1,32 @@
+#ifndef PYTHONIC_NUMPY_FULLLIKE_HPP
+#define PYTHONIC_NUMPY_FULLLIKE_HPP
+
+#include "pythonic/include/numpy/full_like.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/numpy/full.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class E, class F, class dtype>
+ auto full_like(E const &expr, F fill_value, dtype d)
+ -> decltype(full(sutils::getshape(expr), fill_value, d))
+ {
+ return full(sutils::getshape(expr), fill_value, d);
+ }
+
+ template <class E, class F>
+ auto full_like(E const &expr, F fill_value, types::none_type)
+ -> decltype(full(sutils::getshape(expr), fill_value,
+ types::dtype_t<typename E::dtype>()))
+ {
+ return full(sutils::getshape(expr), fill_value,
+ types::dtype_t<typename E::dtype>());
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/greater.hpp b/contrib/python/pythran/pythran/pythonic/numpy/greater.hpp
new file mode 100644
index 00000000000..687d8d546f1
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/greater.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_NUMPY_GREATER_HPP
+#define PYTHONIC_NUMPY_GREATER_HPP
+
+#include "pythonic/include/numpy/greater.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/operator_/gt.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME greater
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::gt
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/greater/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/greater/accumulate.hpp
new file mode 100644
index 00000000000..616f028d969
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/greater/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_GREATER_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_GREATER_ACCUMULATE_HPP
+
+#define UFUNC_NAME greater
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/greater_equal.hpp b/contrib/python/pythran/pythran/pythonic/numpy/greater_equal.hpp
new file mode 100644
index 00000000000..d19a51054d2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/greater_equal.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_NUMPY_GREATEREQUAL_HPP
+#define PYTHONIC_NUMPY_GREATEREQUAL_HPP
+
+#include "pythonic/include/numpy/greater_equal.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/operator_/ge.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME greater_equal
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::ge
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/greater_equal/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/greater_equal/accumulate.hpp
new file mode 100644
index 00000000000..c1a4bb91bc5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/greater_equal/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_GREATER_EQUAL_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_GREATER_EQUAL_ACCUMULATE_HPP
+
+#define UFUNC_NAME greater_equal
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/heaviside.hpp b/contrib/python/pythran/pythran/pythonic/numpy/heaviside.hpp
new file mode 100644
index 00000000000..0bec76ec7da
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/heaviside.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_NUMPY_HEAVISIDE_HPP
+#define PYTHONIC_NUMPY_HEAVISIDE_HPP
+
+#include "pythonic/include/numpy/cos.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ template <class T0, class T1>
+ T1 heaviside(T0 x0, T1 x1)
+ {
+ if (x0 == 0)
+ return x1;
+ if (x0 < 0)
+ return 0;
+ if (x0 > 0)
+ return 1;
+ return x0; // NaN
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME heaviside
+#define NUMPY_NARY_FUNC_SYM details::heaviside
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/heaviside/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/heaviside/accumulate.hpp
new file mode 100644
index 00000000000..a2dfb06bb58
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/heaviside/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_HEAVISIDE_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_HEAVISIDE_ACCUMULATE_HPP
+
+#define UFUNC_NAME heaviside
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/hstack.hpp b/contrib/python/pythran/pythran/pythonic/numpy/hstack.hpp
new file mode 100644
index 00000000000..b707c41f1c3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/hstack.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_NUMPY_HSTACK_HPP
+#define PYTHONIC_NUMPY_HSTACK_HPP
+
+#include <pythonic/include/numpy/hstack.hpp>
+#include <pythonic/numpy/concatenate.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class ArraySequence>
+ auto hstack(ArraySequence &&seq)
+ -> decltype(concatenate(std::forward<ArraySequence>(seq), 1))
+ {
+ auto constexpr concatenate_axis =
+ (decltype(concatenate(std::forward<ArraySequence>(seq), 1))::value !=
+ 1);
+ return concatenate(std::forward<ArraySequence>(seq), concatenate_axis);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/hypot.hpp b/contrib/python/pythran/pythran/pythonic/numpy/hypot.hpp
new file mode 100644
index 00000000000..366ab8bbbbb
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/hypot.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_NUMPY_HYPOT_HPP
+#define PYTHONIC_NUMPY_HYPOT_HPP
+
+#include "pythonic/include/numpy/hypot.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME hypot
+#define NUMPY_NARY_FUNC_SYM xsimd::hypot
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/hypot/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/hypot/accumulate.hpp
new file mode 100644
index 00000000000..913b8bf53e5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/hypot/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_HYPOT_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_HYPOT_ACCUMULATE_HPP
+
+#define UFUNC_NAME hypot
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/identity.hpp b/contrib/python/pythran/pythran/pythonic/numpy/identity.hpp
new file mode 100644
index 00000000000..e065c307074
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/identity.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_NUMPY_IDENTITY_HPP
+#define PYTHONIC_NUMPY_IDENTITY_HPP
+
+#include "pythonic/include/numpy/identity.hpp"
+
+#include "pythonic/numpy/eye.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class dtype>
+ auto identity(long n, dtype d) -> decltype(eye(n, n, 0, d))
+ {
+ return eye(n, n, 0, d);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/imag.hpp b/contrib/python/pythran/pythran/pythonic/numpy/imag.hpp
new file mode 100644
index 00000000000..b27c313eaa3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/imag.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_NUMPY_IMAG_HPP
+#define PYTHONIC_NUMPY_IMAG_HPP
+
+#include "pythonic/include/numpy/imag.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/numpy/asarray.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/list.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ auto imag(E &&expr)
+ -> decltype(builtins::getattr(types::attr::IMAG{}, std::forward<E>(expr)))
+ {
+ return builtins::getattr(types::attr::IMAG{}, std::forward<E>(expr));
+ }
+
+ template <class T>
+ auto imag(types::list<T> const &expr)
+ -> decltype(imag(numpy::functor::asarray{}(expr)))
+ {
+ return imag(numpy::functor::asarray{}(expr));
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/indices.hpp b/contrib/python/pythran/pythran/pythonic/numpy/indices.hpp
new file mode 100644
index 00000000000..01b6dc7994e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/indices.hpp
@@ -0,0 +1,49 @@
+#ifndef PYTHONIC_NUMPY_INDICES_HPP
+#define PYTHONIC_NUMPY_INDICES_HPP
+
+#include "pythonic/include/numpy/indices.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class pS, class dtype>
+ types::ndarray<
+ typename dtype::type,
+ sutils::push_front_t<
+ pS, std::integral_constant<long, std::tuple_size<pS>::value>>>
+ indices(pS const &shape, dtype)
+ {
+ auto constexpr N = std::tuple_size<pS>::value;
+ sutils::push_front_t<pS, std::integral_constant<long, N>> oshape;
+ sutils::scopy_shape<1, -1>(oshape, shape, utils::make_index_sequence<N>());
+ types::ndarray<typename dtype::type,
+ sutils::push_front_t<pS, std::integral_constant<long, N>>>
+ out(oshape, builtins::None);
+ typename dtype::type *iters[N];
+ for (size_t n = 0; n < N; ++n)
+ iters[n] = out[n].buffer;
+ size_t lens[N];
+ lens[0] = out.flat_size() / std::get<0>(shape);
+
+ auto ashape = sutils::array(shape);
+
+ for (size_t n = 1; n < N; ++n)
+ lens[n] = lens[n - 1] / ashape[n];
+ for (long i = 0, n = out.flat_size() / N; i < n; ++i) {
+ long mult = 1;
+ for (long n = N - 1; n > 0; n--) {
+ *(iters[n]++) = (i / mult) % ashape[n];
+ mult *= ashape[n];
+ }
+ *(iters[0]++) = i / mult;
+ }
+ return out;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/inner.hpp b/contrib/python/pythran/pythran/pythonic/numpy/inner.hpp
new file mode 100644
index 00000000000..b3ca735833c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/inner.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_INNER_HPP
+#define PYTHONIC_NUMPY_INNER_HPP
+
+#include "pythonic/include/numpy/inner.hpp"
+#include "pythonic/numpy/dot.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/insert.hpp b/contrib/python/pythran/pythran/pythonic/numpy/insert.hpp
new file mode 100644
index 00000000000..ea09fade897
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/insert.hpp
@@ -0,0 +1,79 @@
+#ifndef PYTHONIC_NUMPY_INSERT_HPP
+#define PYTHONIC_NUMPY_INSERT_HPP
+
+#include "pythonic/include/numpy/insert.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/traits.hpp"
+#include "pythonic/builtins/None.hpp"
+
+#include <algorithm>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class T, class pS, class I, class F>
+ typename std::enable_if<types::is_iterable<I>::value &&
+ types::is_iterable<F>::value,
+ types::ndarray<T, types::pshape<long>>>::type
+ insert(types::ndarray<T, pS> in, I const &indices, F const &data,
+ types::none_type axis)
+ {
+ types::ndarray<T, types::pshape<long>> out(
+ types::pshape<long>(long(
+ in.flat_size() + std::min(indices.flat_size(), data.flat_size()))),
+ builtins::None);
+ auto out_iter = out.fbegin();
+ auto in_iter = in.fbegin();
+ auto data_iter = data.begin();
+ for (long index : indices) {
+ out_iter = std::copy(in_iter, in.fbegin() + index, out_iter);
+ *out_iter++ = *data_iter++;
+ in_iter = in.fbegin() + index;
+ }
+ std::copy(in_iter, in.fend(), out_iter);
+ return out;
+ }
+
+ template <class T, class pS, class I, class F>
+ typename std::enable_if<types::is_iterable<I>::value &&
+ !types::is_iterable<F>::value,
+ types::ndarray<T, types::pshape<long>>>::type
+ insert(types::ndarray<T, pS> in, I const &indices, F const &data,
+ types::none_type axis)
+ {
+ return insert(in, indices, types::list<F>({data}), axis);
+ }
+
+ template <class T, class pS, class I, class F>
+ typename std::enable_if<!types::is_iterable<I>::value &&
+ types::is_iterable<F>::value,
+ types::ndarray<T, types::pshape<long>>>::type
+ insert(types::ndarray<T, pS> in, I const &indices, F const &data,
+ types::none_type axis)
+ {
+ return insert(in, types::list<I>({indices}), {data}, axis);
+ }
+
+ template <class T, class pS, class I, class F>
+ typename std::enable_if<!types::is_iterable<I>::value &&
+ !types::is_iterable<F>::value,
+ types::ndarray<T, types::pshape<long>>>::type
+ insert(types::ndarray<T, pS> in, I const &indices, F const &data,
+ types::none_type axis)
+ {
+ return insert(in, types::list<I>({indices}), types::list<F>({data}), axis);
+ }
+
+ template <class E, class... Args>
+ E insert(E, Args const &...)
+ {
+ throw std::runtime_error("insert only partially supported");
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/int_.hpp b/contrib/python/pythran/pythran/pythonic/numpy/int_.hpp
new file mode 100644
index 00000000000..6c336194f6c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/int_.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_NUMPY_INT__HPP
+#define PYTHONIC_NUMPY_INT__HPP
+
+#include "pythonic/include/numpy/int_.hpp"
+
+#include "pythonic/types/numpy_op_helper.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/meta.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ inline long int_()
+ {
+ return {};
+ }
+
+ template <class V>
+ long int_(V v)
+ {
+ return static_cast<long>(v);
+ }
+ } // namespace details
+
+#define NUMPY_NARY_FUNC_NAME int_
+#define NUMPY_NARY_FUNC_SYM details::int_
+#include "pythonic/types/numpy_nary_expr.hpp"
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/intc.hpp b/contrib/python/pythran/pythran/pythonic/numpy/intc.hpp
new file mode 100644
index 00000000000..f47b6d8879c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/intc.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_NUMPY_INTC_HPP
+#define PYTHONIC_NUMPY_INTC_HPP
+
+#include "pythonic/include/numpy/intc.hpp"
+
+#include "pythonic/types/numpy_op_helper.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/meta.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ inline int intc()
+ {
+ return {};
+ }
+
+ template <class V>
+ int intc(V v)
+ {
+ return v;
+ }
+ } // namespace details
+
+#define NUMPY_NARY_FUNC_NAME intc
+#define NUMPY_NARY_FUNC_SYM details::intc
+#include "pythonic/types/numpy_nary_expr.hpp"
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/interp.hpp b/contrib/python/pythran/pythran/pythonic/numpy/interp.hpp
new file mode 100644
index 00000000000..3b0993a3410
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/interp.hpp
@@ -0,0 +1,198 @@
+#ifndef PYTHONIC_NUMPY_INTERP_HPP
+#define PYTHONIC_NUMPY_INTERP_HPP
+
+#include "pythonic/include/numpy/argsort.hpp"
+#include "pythonic/include/numpy/interp.hpp"
+#include "pythonic/include/numpy/remainder.hpp"
+#include <pythonic/include/numpy/concatenate.hpp>
+
+#include "pythonic/numpy/argsort.hpp"
+#include <pythonic/numpy/concatenate.hpp>
+#include <pythonic/numpy/remainder.hpp>
+
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/numpy/interp_core.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_conversion.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T1, class T2, class T3, typename t1, typename t2, typename t3>
+ types::ndarray<interp_out_type<T3>, types::pshape<long>>
+ interp(T1 x, T2 xp, T3 fp, t1 _left, t2 _right, t3 _period)
+ {
+ interp_out_type<T3> left = _left;
+ interp_out_type<T3> right = _right;
+ double period = _period;
+ // Todo: what to do if this condition isn't satisfied? Can't use a statis
+ // assert because the size isn't known at compile time.
+ assert(xp.template shape<0>() == fp.template shape<0>());
+ interp_out_type<T3> outVal(0);
+
+ types::ndarray<interp_out_type<T3>, types::pshape<long>> out = {
+ (long)(x.template shape<0>()), outVal};
+
+ if (period) {
+ auto x_rem = pythonic::numpy::functor::remainder{}(x, period);
+ auto xp_rem = pythonic::numpy::functor::remainder{}(xp, period);
+ auto idx = pythonic::numpy::functor::argsort{}(xp_rem);
+ auto xp_sorted = xp_rem[idx];
+ auto fp_sorted = fp[idx];
+
+ auto left_pad_xp =
+ types::ndarray<typename T2::dtype, types::pshape<long>>(
+ types::pshape<long>(1), xp_sorted[-1] - period);
+ auto right_pad_xp =
+ types::ndarray<typename T2::dtype, types::pshape<long>>(
+ types::pshape<long>(1), xp_sorted[0] + period);
+ auto new_xp = pythonic::numpy::functor::concatenate{}(
+ pythonic::types::make_tuple(left_pad_xp, xp_sorted, right_pad_xp));
+
+ auto left_pad_fp =
+ types::ndarray<interp_out_type<T3>, types::pshape<long>>(
+ types::pshape<long>(1), fp_sorted[-1]);
+ auto right_pad_fp =
+ types::ndarray<interp_out_type<T3>, types::pshape<long>>(
+ types::pshape<long>(1), fp_sorted[0]);
+ auto new_fp = pythonic::numpy::functor::concatenate{}(
+ pythonic::types::make_tuple(left_pad_fp, fp_sorted, right_pad_fp));
+
+ auto lenxp = new_xp.size();
+ auto lenx = x_rem.size();
+ do_interp(x_rem, new_xp, new_fp, out, lenxp, lenx, 0., 0.);
+ } else {
+ auto lenxp = xp.size();
+ auto lenx = x.size();
+ do_interp(x, xp, fp, out, lenxp, lenx, left, right);
+ }
+
+ return out;
+ }
+
+ // No parameter specified
+ template <class T1, class T2, class T3>
+ typename std::enable_if<
+ !std::is_arithmetic<T1>::value,
+ types::ndarray<interp_out_type<T3>, types::pshape<long>>>::type
+ interp(T1 x, T2 xp, T3 fp, types::none_type left, types::none_type right,
+ types::none_type period)
+ {
+ auto _left = fp[0];
+ auto _right = fp[-1];
+ return interp(x, xp, fp, _left, _right, 0.);
+ }
+
+ // left specified
+ template <class T1, class T2, class T3, typename t1>
+ typename std::enable_if<
+ !std::is_arithmetic<T1>::value,
+ types::ndarray<interp_out_type<T3>, types::pshape<long>>>::type
+ interp(T1 x, T2 xp, T3 fp, t1 left, types::none_type right,
+ types::none_type period)
+ {
+ auto _right = fp[-1];
+ return interp(x, xp, fp, left, _right, 0.);
+ }
+ // right specified
+ template <class T1, class T2, class T3, typename t1>
+ typename std::enable_if<
+ !std::is_arithmetic<T1>::value,
+ types::ndarray<interp_out_type<T3>, types::pshape<long>>>::type
+ interp(T1 x, T2 xp, T3 fp, types::none_type left, t1 right,
+ types::none_type period)
+ {
+ auto _left = fp[0];
+ return interp(x, xp, fp, _left, right, 0.);
+ }
+ // period specified
+ template <class T1, class T2, class T3, typename t1>
+ typename std::enable_if<
+ !std::is_arithmetic<T1>::value,
+ types::ndarray<interp_out_type<T3>, types::pshape<long>>>::type
+ interp(T1 x, T2 xp, T3 fp, types::none_type left, types::none_type right,
+ t1 period)
+ {
+ assert(period != 0);
+ return interp(x, xp, fp, 0., 0., period);
+ }
+
+ // left and right specified
+ template <class T1, class T2, class T3, typename t1, typename t2>
+ typename std::enable_if<
+ !std::is_arithmetic<T1>::value,
+ types::ndarray<interp_out_type<T3>, types::pshape<long>>>::type
+ interp(T1 x, T2 xp, T3 fp, t1 left, t2 right, types::none_type period)
+ {
+ return interp(x, xp, fp, left, right, 0.);
+ }
+
+ // No parameter specified
+ template <class T1, class T2, class T3>
+ typename std::enable_if<std::is_arithmetic<T1>::value,
+ interp_out_type<T3>>::type
+ interp(T1 x, T2 xp, T3 fp, types::none_type left, types::none_type right,
+ types::none_type period)
+ {
+ auto _left = fp[0];
+ auto _right = fp[-1];
+ auto temp_array =
+ types::ndarray<double, types::pshape<long>>(types::pshape<long>(1), x);
+ return interp(temp_array, xp, fp, _left, _right, 0.)[0];
+ }
+
+ // left specified
+ template <class T1, class T2, class T3, typename t1>
+ typename std::enable_if<std::is_arithmetic<T1>::value,
+ interp_out_type<T3>>::type
+ interp(T1 x, T2 xp, T3 fp, t1 left, types::none_type right,
+ types::none_type period)
+ {
+ auto _right = fp[-1];
+ auto temp_array =
+ types::ndarray<double, types::pshape<long>>(types::pshape<long>(1), x);
+ return interp(temp_array, xp, fp, left, _right, 0.)[0];
+ }
+ // right specified
+ template <class T1, class T2, class T3, typename t1>
+ typename std::enable_if<std::is_arithmetic<T1>::value,
+ interp_out_type<T3>>::type
+ interp(T1 x, T2 xp, T3 fp, types::none_type left, t1 right,
+ types::none_type period)
+ {
+ auto _left = fp[0];
+ auto temp_array =
+ types::ndarray<double, types::pshape<long>>(types::pshape<long>(1), x);
+ return interp(temp_array, xp, fp, _left, right, 0.)[0];
+ }
+ // period specified
+ template <class T1, class T2, class T3, typename t1>
+ typename std::enable_if<std::is_arithmetic<T1>::value,
+ interp_out_type<T3>>::type
+ interp(T1 x, T2 xp, T3 fp, types::none_type left, types::none_type right,
+ t1 period)
+ {
+ assert(period != 0);
+ auto temp_array =
+ types::ndarray<double, types::pshape<long>>(types::pshape<long>(1), x);
+ return interp(temp_array, xp, fp, 0., 0., period)[0];
+ }
+
+ // left and right specified,
+ template <class T1, class T2, class T3, typename t1, typename t2>
+ typename std::enable_if<std::is_arithmetic<T1>::value,
+ interp_out_type<T3>>::type
+ interp(T1 x, T2 xp, T3 fp, t1 left, t2 right, types::none_type period)
+ {
+ auto temp_array =
+ types::ndarray<double, types::pshape<long>>(types::pshape<long>(1), x);
+ return interp(temp_array, xp, fp, left, right, 0.)[0];
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(interp);
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/interp_core.hpp b/contrib/python/pythran/pythran/pythonic/numpy/interp_core.hpp
new file mode 100644
index 00000000000..93da77f9990
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/interp_core.hpp
@@ -0,0 +1,258 @@
+//
+// From NumpySrc/numpy/core/src/multiarray/compiled_base.c
+
+/** @brief find index of a sorted array such that arr[i] <= key < arr[i + 1].
+ *
+ * If an starting index guess is in-range, the array values around this
+ * index are first checked. This allows for repeated calls for well-ordered
+ * keys (a very common case) to use the previous index as a very good guess.
+ *
+ * If the guess value is not useful, bisection of the array is used to
+ * find the index. If there is no such index, the return values are:
+ * key < arr[0] -- -1
+ * key == arr[len - 1] -- len - 1
+ * key > arr[len - 1] -- len
+ * The array is assumed contiguous and sorted in ascending order.
+ *
+ * @param key key value.
+ * @param arr contiguous sorted array to be searched.
+ * @param len length of the array.
+ * @param guess initial guess of index
+ * @return index
+ */
+#include "pythonic/numpy/isnan.hpp"
+#include "pythonic/utils/allocate.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#define LIKELY_IN_CACHE_SIZE 8
+PYTHONIC_NS_BEGIN
+
+template <typename npy_intp, typename npy_double, class T>
+static npy_intp binary_search_with_guess(const npy_double key, const T &arr,
+ npy_intp len, npy_intp guess)
+{
+ npy_intp imin = 0;
+ npy_intp imax = len;
+
+ /* Handle keys outside of the arr range first */
+ if (key > arr[len - 1]) {
+ return len;
+ } else if (key < arr[0]) {
+ return -1;
+ }
+
+ /*
+ * If len <= 4 use linear search.
+ * From above we know key >= arr[0] when we start.
+ */
+ if (len <= 4) {
+ npy_intp i;
+
+ for (i = 1; i < len && key >= arr[i]; ++i)
+ ;
+ return i - 1;
+ }
+
+ if (guess > len - 3) {
+ guess = len - 3;
+ }
+ if (guess < 1) {
+ guess = 1;
+ }
+
+ /* check most likely values: guess - 1, guess, guess + 1 */
+ if (key < arr[guess]) {
+ if (key < arr[guess - 1]) {
+ imax = guess - 1;
+ /* last attempt to restrict search to items in cache */
+ if (guess > LIKELY_IN_CACHE_SIZE &&
+ key >= arr[guess - LIKELY_IN_CACHE_SIZE]) {
+ imin = guess - LIKELY_IN_CACHE_SIZE;
+ }
+ } else {
+ /* key >= arr[guess - 1] */
+ return guess - 1;
+ }
+ } else {
+ /* key >= arr[guess] */
+ if (key < arr[guess + 1]) {
+ return guess;
+ } else {
+ /* key >= arr[guess + 1] */
+ if (key < arr[guess + 2]) {
+ return guess + 1;
+ } else {
+ /* key >= arr[guess + 2] */
+ imin = guess + 2;
+ /* last attempt to restrict search to items in cache */
+ if (guess < len - LIKELY_IN_CACHE_SIZE - 1 &&
+ key < arr[guess + LIKELY_IN_CACHE_SIZE]) {
+ imax = guess + LIKELY_IN_CACHE_SIZE;
+ }
+ }
+ }
+ }
+
+ /* finally, find index by bisection */
+ while (imin < imax) {
+ const npy_intp imid = imin + ((imax - imin) >> 1);
+ if (key >= arr[imid]) {
+ imin = imid + 1;
+ } else {
+ imax = imid;
+ }
+ }
+ return imin - 1;
+}
+//
+// #undef LIKELY_IN_CACHE_SIZE
+//
+// NPY_NO_EXPORT PyObject *
+// arr_interp(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwdict)
+//{
+//
+// PyObject *fp, *xp, *x;
+// PyObject *left = NULL, *right = NULL;
+// PyArrayObject *afp = NULL, *axp = NULL, *ax = NULL, *af = NULL;
+// npy_intp i, lenx, lenxp;
+// double lval, rval;
+// const double *dy, *dx, *dz;
+// double *dres, *slopes = NULL;
+//
+// static char *kwlist[] = {"x", "xp", "fp", "left", "right", NULL};
+//
+// NPY_BEGIN_THREADS_DEF;
+//
+// if (!PyArg_ParseTupleAndKeywords(args, kwdict, "OOO|OO:interp", kwlist,
+// &x, &xp, &fp, &left, &right)) {
+// return NULL;
+// }
+//
+// afp = (PyArrayObject *)PyArray_ContiguousFromAny(fp, double, 1, 1);
+// if (afp == NULL) {
+// return NULL;
+// }
+// axp = (PyArrayObject *)PyArray_ContiguousFromAny(xp, double, 1, 1);
+// if (axp == NULL) {
+// goto fail;
+// }
+// ax = (PyArrayObject *)PyArray_ContiguousFromAny(x, double, 0, 0);
+// if (ax == NULL) {
+// goto fail;
+// }
+// lenxp = PyArray_SIZE(axp);
+// if (lenxp == 0) {
+// PyErr_SetString(PyExc_ValueError,
+// "array of sample points is empty");
+// goto fail;
+// }
+// if (PyArray_SIZE(afp) != lenxp) {
+// PyErr_SetString(PyExc_ValueError,
+// "fp and xp are not of the same length.");
+// goto fail;
+// }
+//
+// af = (PyArrayObject *)PyArray_SimpleNew(PyArray_NDIM(ax),
+// PyArray_DIMS(ax), double);
+// if (af == NULL) {
+// goto fail;
+// }
+// lenx = PyArray_SIZE(ax);
+//
+// dy = (const double *)PyArray_DATA(afp);
+// dx = (const double *)PyArray_DATA(axp);
+// dz = (const double *)PyArray_DATA(ax);
+// dres = (double *)PyArray_DATA(af);
+// /* Get left and right fill values. */
+// if ((left == NULL) || (left == Py_None)) {
+// lval = dy[0];
+// }
+// else {
+// lval = PyFloat_AsDouble(left);
+// if (error_converting(lval)) {
+// goto fail;
+// }
+// }
+// if ((right == NULL) || (right == Py_None)) {
+// rval = dy[lenxp - 1];
+// }
+// else {
+// rval = PyFloat_AsDouble(right);
+// if (error_converting(rval)) {
+// goto fail;
+// }
+// }
+
+// xp->dx fp->dy x -> dz
+// This is the output type, based on the type of T, which can be complex.
+template <class T>
+using out_type =
+ typename std::conditional<types::is_complex<typename T::dtype>::value,
+ std::complex<double>, double>::type;
+
+template <typename npy_intp, typename T5, class T1, class T2, class T3,
+ class T4>
+void do_interp(const T1 &dz, const T2 &dx, const T3 &dy, T4 &dres,
+ npy_intp lenxp, npy_intp lenx, T5 lval, T5 rval)
+{
+ npy_intp i;
+ out_type<T3> *slopes = NULL;
+ std::vector<out_type<T3>, utils::allocator<out_type<T3>>> slope_vect;
+ /* binary_search_with_guess needs at least a 3 item long array */
+ if (lenxp == 1) {
+ const double xp_val = dx[0];
+ const out_type<T3> fp_val = dy[0];
+
+ // NPY_BEGIN_THREADS_THRESHOLDED(lenx);
+ for (i = 0; i < lenx; ++i) {
+ const double x_val = dz[i];
+ dres[i] = (x_val < xp_val) ? lval : ((x_val > xp_val) ? rval : fp_val);
+ }
+ // NPY_END_THREADS;
+ } else {
+ npy_intp j = 0;
+
+ /* only pre-calculate slopes if there are relatively few of them. */
+ if (lenxp <= lenx) {
+ slope_vect.resize(lenxp - 1);
+ slopes = slope_vect.data();
+ }
+
+ // NPY_BEGIN_THREADS;
+
+ if (slopes != NULL) {
+ for (i = 0; i < lenxp - 1; ++i) {
+ slopes[i] = (dy[i + 1] - dy[i]) / (dx[i + 1] - dx[i]);
+ }
+ }
+
+ for (i = 0; i < lenx; ++i) {
+ const double x_val = dz[i];
+
+ if (pythonic::numpy::functor::isnan()(x_val)) {
+ dres[i] = x_val;
+ continue;
+ }
+
+ j = binary_search_with_guess(x_val, dx, lenxp, j);
+ if (j == -1) {
+ dres[i] = lval;
+ } else if (j == lenxp) {
+ dres[i] = rval;
+ } else if (j == lenxp - 1) {
+ dres[i] = dy[j];
+ } else if (dx[j] == x_val) {
+ /* Avoid potential non-finite interpolation */
+ dres[i] = dy[j];
+ } else {
+ const out_type<T3> slope =
+ (slopes != NULL) ? slopes[j]
+ : (dy[j + 1] - dy[j]) / (dx[j + 1] - dx[j]);
+ dres[i] = slope * (x_val - dx[j]) + dy[j];
+ }
+ }
+
+ // NPY_END_THREADS;
+ }
+}
+PYTHONIC_NS_END
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/intersect1d.hpp b/contrib/python/pythran/pythran/pythonic/numpy/intersect1d.hpp
new file mode 100644
index 00000000000..ca9f974dfd6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/intersect1d.hpp
@@ -0,0 +1,45 @@
+#ifndef PYTHONIC_NUMPY_INTERSECT1D_HPP
+#define PYTHONIC_NUMPY_INTERSECT1D_HPP
+
+#include "pythonic/include/numpy/intersect1d.hpp"
+
+#include "pythonic/numpy/asarray.hpp"
+#include "pythonic/types/combined.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/pdqsort.hpp"
+
+#include <algorithm>
+#include <set>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E, class F>
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::pshape<long>>
+ intersect1d(E const &e, F const &f)
+ {
+ using T = typename __combined<typename E::dtype, typename F::dtype>::type;
+ auto ae = asarray(e);
+ auto af = asarray(f);
+ std::set<T, std::less<T>, utils::allocator<T>> sae(ae.fbegin(), ae.fend());
+ std::set<T, std::less<T>, utils::allocator<T>> found;
+ types::list<T> lout(0);
+ lout.reserve(sae.size());
+ for (auto iter = af.fbegin(), end = af.fend(); iter != end; ++iter) {
+ auto curr = *iter;
+ if (sae.find(curr) != sae.end() && found.find(curr) == found.end()) {
+ found.insert(curr);
+ lout.push_back(curr);
+ }
+ }
+ pdqsort(lout.begin(), lout.end());
+ return {lout};
+ }
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/invert.hpp b/contrib/python/pythran/pythran/pythonic/numpy/invert.hpp
new file mode 100644
index 00000000000..0bccba8bf0c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/invert.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_NUMPY_INVERT_HPP
+#define PYTHONIC_NUMPY_INVERT_HPP
+
+#include "pythonic/include/numpy/invert.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/operator_/invert.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME invert
+#define NUMPY_NARY_FUNC_SYM operator_::invert
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/isclose.hpp b/contrib/python/pythran/pythran/pythonic/numpy/isclose.hpp
new file mode 100644
index 00000000000..84d5068eadc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/isclose.hpp
@@ -0,0 +1,36 @@
+#ifndef PYTHONIC_NUMPY_ISCLOSE_HPP
+#define PYTHONIC_NUMPY_ISCLOSE_HPP
+
+#include "pythonic/include/numpy/isclose.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/numpy/abs.hpp"
+#include "pythonic/numpy/isfinite.hpp"
+#include "pythonic/numpy/isnan.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+
+ namespace wrapper
+ {
+ template <class T0, class T1>
+ bool isclose(T0 const &u, T1 const &v, double rtol, double atol,
+ bool equal_nan)
+ {
+ if (functor::isfinite()(u) && functor::isfinite()(v))
+ return functor::abs()(u - v) <= (atol + rtol * functor::abs()(v));
+ else if (functor::isnan()(u) && functor::isnan()(v))
+ return equal_nan;
+ else
+ return (u == v);
+ }
+ }
+#define NUMPY_NARY_FUNC_NAME isclose
+#define NUMPY_NARY_FUNC_SYM wrapper::isclose
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/iscomplex.hpp b/contrib/python/pythran/pythran/pythonic/numpy/iscomplex.hpp
new file mode 100644
index 00000000000..3d0b8361910
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/iscomplex.hpp
@@ -0,0 +1,39 @@
+#ifndef PYTHONIC_NUMPY_ISCOMPLEX_HPP
+#define PYTHONIC_NUMPY_ISCOMPLEX_HPP
+
+#include "pythonic/include/numpy/iscomplex.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/types/traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace wrapper
+ {
+ template <class I>
+ typename std::enable_if<types::is_complex<I>::value, bool>::type
+ iscomplex(I const &a)
+ {
+ return a.imag() != 0.;
+ }
+
+ template <class I>
+ constexpr typename std::enable_if<!types::is_complex<I>::value, bool>::type
+ iscomplex(I const &a)
+ {
+ return false;
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME iscomplex
+#define NUMPY_NARY_FUNC_SYM wrapper::iscomplex
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/isfinite.hpp b/contrib/python/pythran/pythran/pythonic/numpy/isfinite.hpp
new file mode 100644
index 00000000000..fd07a6abc77
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/isfinite.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_NUMPY_ISFINITE_HPP
+#define PYTHONIC_NUMPY_ISFINITE_HPP
+
+#include "pythonic/include/numpy/isfinite.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME isfinite
+#define NUMPY_NARY_FUNC_SYM wrapper::isfinite
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/isinf.hpp b/contrib/python/pythran/pythran/pythonic/numpy/isinf.hpp
new file mode 100644
index 00000000000..c17e9277da9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/isinf.hpp
@@ -0,0 +1,33 @@
+#ifndef PYTHONIC_NUMPY_ISINF_HPP
+#define PYTHONIC_NUMPY_ISINF_HPP
+
+#include "pythonic/include/numpy/isinf.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T>
+ bool isinf(T const &v)
+ {
+ return std::isinf(v);
+ }
+ template <class T>
+ bool isinf(std::complex<T> const &v)
+ {
+ return std::isinf(v.real()) || std::isinf(v.imag());
+ }
+ }
+#define NUMPY_NARY_FUNC_NAME isinf
+#define NUMPY_NARY_FUNC_SYM wrapper::isinf
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/isnan.hpp b/contrib/python/pythran/pythran/pythonic/numpy/isnan.hpp
new file mode 100644
index 00000000000..781907281c8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/isnan.hpp
@@ -0,0 +1,44 @@
+#ifndef PYTHONIC_NUMPY_ISNAN_HPP
+#define PYTHONIC_NUMPY_ISNAN_HPP
+
+#include "pythonic/include/numpy/isnan.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T>
+ bool isnan(std::complex<T> const &v)
+ {
+ return std::isnan(v.real()) || std::isnan(v.imag());
+ }
+
+ template <class T>
+ auto isnan(T const &v) -> typename std::enable_if<
+ std::is_floating_point<typename std::decay<T>::type>::value, bool>::type
+ {
+ return std::isnan(v);
+ }
+
+ template <class T>
+ auto isnan(T const &v) -> typename std::enable_if<
+ !std::is_floating_point<typename std::decay<T>::type>::value,
+ bool>::type
+ {
+ return false;
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME isnan
+#define NUMPY_NARY_FUNC_SYM wrapper::isnan
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/isneginf.hpp b/contrib/python/pythran/pythran/pythonic/numpy/isneginf.hpp
new file mode 100644
index 00000000000..e6fdc781328
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/isneginf.hpp
@@ -0,0 +1,30 @@
+#ifndef PYTHONIC_NUMPY_ISNEGINF_HPP
+#define PYTHONIC_NUMPY_ISNEGINF_HPP
+
+#include "pythonic/include/numpy/isneginf.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic//numpy/isinf.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T>
+ auto isneginf(T const &t) -> decltype(functor::isinf{}(t) && (t < 0))
+ {
+ return functor::isinf{}(t) && (t < 0);
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME isneginf
+#define NUMPY_NARY_FUNC_SYM wrapper::isneginf
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/isposinf.hpp b/contrib/python/pythran/pythran/pythonic/numpy/isposinf.hpp
new file mode 100644
index 00000000000..b1952a792e2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/isposinf.hpp
@@ -0,0 +1,30 @@
+#ifndef PYTHONIC_NUMPY_ISPOSINF_HPP
+#define PYTHONIC_NUMPY_ISPOSINF_HPP
+
+#include "pythonic/include/numpy/isposinf.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+#include "pythonic/numpy/isinf.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T>
+ auto isposinf(T const &t) -> decltype(functor::isinf{}(t) && t >= 0)
+ {
+ return functor::isinf{}(t) && t >= 0;
+ }
+ }
+#define NUMPY_NARY_FUNC_NAME isposinf
+#define NUMPY_NARY_FUNC_SYM wrapper::isposinf
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/isreal.hpp b/contrib/python/pythran/pythran/pythonic/numpy/isreal.hpp
new file mode 100644
index 00000000000..2e3e17d2d8c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/isreal.hpp
@@ -0,0 +1,39 @@
+#ifndef PYTHONIC_NUMPY_ISREAL_HPP
+#define PYTHONIC_NUMPY_ISREAL_HPP
+
+#include "pythonic/include/numpy/isreal.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/types/traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace wrapper
+ {
+ template <class I>
+ typename std::enable_if<types::is_complex<I>::value, bool>::type
+ isreal(I const &a)
+ {
+ return a.imag() == 0.;
+ }
+
+ template <class I>
+ typename std::enable_if<!types::is_complex<I>::value, bool>::type
+ isreal(I const &a)
+ {
+ return true;
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME isreal
+#define NUMPY_NARY_FUNC_SYM wrapper::isreal
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/isrealobj.hpp b/contrib/python/pythran/pythran/pythonic/numpy/isrealobj.hpp
new file mode 100644
index 00000000000..f8207f9a98b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/isrealobj.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_NUMPY_ISREALOBJ_HPP
+#define PYTHONIC_NUMPY_ISREALOBJ_HPP
+
+#include "pythonic/include/numpy/isrealobj.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ constexpr bool isrealobj(E const &expr)
+ {
+ return !types::is_complex<typename E::dtype>::value;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/isscalar.hpp b/contrib/python/pythran/pythran/pythonic/numpy/isscalar.hpp
new file mode 100644
index 00000000000..56b5fcc289e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/isscalar.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_NUMPY_ISSCALAR_HPP
+#define PYTHONIC_NUMPY_ISSCALAR_HPP
+
+#include "pythonic/include/numpy/isscalar.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/traits.hpp"
+#include "pythonic/types/str.hpp"
+
+#include <type_traits>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ constexpr bool isscalar(E const &)
+ {
+ return types::is_dtype<E>::value || std::is_same<E, types::str>::value;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/issctype.hpp b/contrib/python/pythran/pythran/pythonic/numpy/issctype.hpp
new file mode 100644
index 00000000000..368fbd02d31
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/issctype.hpp
@@ -0,0 +1,32 @@
+#ifndef PYTHONIC_NUMPY_ISSCTYPE_HPP
+#define PYTHONIC_NUMPY_ISSCTYPE_HPP
+
+#include "pythonic/include/numpy/issctype.hpp"
+
+#include "pythonic/numpy/isscalar.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ constexpr auto issctype(E const &expr) ->
+ typename std::enable_if<!types::is_dtype<E>::value &&
+ !std::is_same<E, types::str>::value,
+ bool>::type
+ {
+ return isscalar(typename E::type());
+ }
+
+ template <class E>
+ constexpr auto issctype(E const &expr) ->
+ typename std::enable_if<types::is_dtype<E>::value ||
+ std::is_same<E, types::str>::value,
+ bool>::type
+ {
+ return false;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ldexp.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ldexp.hpp
new file mode 100644
index 00000000000..3671315d6ee
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ldexp.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_NUMPY_LDEXP_HPP
+#define PYTHONIC_NUMPY_LDEXP_HPP
+
+#include "pythonic/include/numpy/ldexp.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME ldexp
+#define NUMPY_NARY_FUNC_SYM std::ldexp
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ldexp/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ldexp/accumulate.hpp
new file mode 100644
index 00000000000..5db2c0cbc89
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ldexp/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_LDEXP_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_LDEXP_ACCUMULATE_HPP
+
+#define UFUNC_NAME ldexp
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/left_shift.hpp b/contrib/python/pythran/pythran/pythonic/numpy/left_shift.hpp
new file mode 100644
index 00000000000..c4b2c747631
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/left_shift.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_NUMPY_LEFT_SHIFT_HPP
+#define PYTHONIC_NUMPY_LEFT_SHIFT_HPP
+
+#include "pythonic/include/numpy/left_shift.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/operator_/lshift.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME left_shift
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::lshift
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/left_shift/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/left_shift/accumulate.hpp
new file mode 100644
index 00000000000..82b73063741
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/left_shift/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_LEFT_SHIFT_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_LEFT_SHIFT_ACCUMULATE_HPP
+
+#define UFUNC_NAME left_shift
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/less.hpp b/contrib/python/pythran/pythran/pythonic/numpy/less.hpp
new file mode 100644
index 00000000000..e1ef9744f68
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/less.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_NUMPY_LESS_HPP
+#define PYTHONIC_NUMPY_LESS_HPP
+
+#include "pythonic/include/numpy/less.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/operator_/lt.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME less
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::lt
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/less/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/less/accumulate.hpp
new file mode 100644
index 00000000000..3b8ea08f825
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/less/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_LESS_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_LESS_ACCUMULATE_HPP
+
+#define UFUNC_NAME less
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/less_equal.hpp b/contrib/python/pythran/pythran/pythonic/numpy/less_equal.hpp
new file mode 100644
index 00000000000..258e83108e2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/less_equal.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_NUMPY_LESSEQUAL_HPP
+#define PYTHONIC_NUMPY_LESSEQUAL_HPP
+
+#include "pythonic/include/numpy/less_equal.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/operator_/le.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME less_equal
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::le
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/less_equal/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/less_equal/accumulate.hpp
new file mode 100644
index 00000000000..53067a3d0b2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/less_equal/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_LESS_EQUAL_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_LESS_EQUAL_ACCUMULATE_HPP
+
+#define UFUNC_NAME less_equal
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/lexsort.hpp b/contrib/python/pythran/pythran/pythonic/numpy/lexsort.hpp
new file mode 100644
index 00000000000..eef50a93fdb
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/lexsort.hpp
@@ -0,0 +1,68 @@
+#ifndef PYTHONIC_NUMPY_LEXSORT_HPP
+#define PYTHONIC_NUMPY_LEXSORT_HPP
+
+#include "pythonic/include/numpy/lexsort.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/pdqsort.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ template <size_t I>
+ struct lexcmp_nth {
+ template <class K>
+ bool operator()(K const &keys, long i0, long i1) const
+ {
+ if (std::get<I - 1>(keys)[i0] < std::get<I - 1>(keys)[i1])
+ return true;
+ else if (std::get<I - 1>(keys)[i0] > std::get<I - 1>(keys)[i1])
+ return false;
+ else
+ return lexcmp_nth<I - 1>{}(keys, i0, i1);
+ }
+ };
+ template <>
+ struct lexcmp_nth<0> {
+ template <class K>
+ bool operator()(K const &keys, long i0, long i1) const
+ {
+ return false;
+ }
+ };
+
+ template <class K>
+ struct lexcmp {
+ K const &keys;
+ lexcmp(K const &keys) : keys(keys)
+ {
+ }
+ bool operator()(long i0, long i1)
+ {
+ return lexcmp_nth<std::tuple_size<K>::value>{}(keys, i0, i1);
+ }
+ };
+ }
+
+ template <class pS>
+ types::ndarray<long, types::pshape<long>> lexsort(pS const &keys)
+ {
+ long n = std::get<0>(keys).size();
+ types::ndarray<long, types::pshape<long>> out(types::pshape<long>(n),
+ builtins::None);
+ // fill with the original indices
+ std::iota(out.buffer, out.buffer + n, 0L);
+ // then sort using keys as the comparator
+ pdqsort(out.buffer, out.buffer + n, details::lexcmp<pS>(keys));
+ return out;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/linalg/matrix_power.hpp b/contrib/python/pythran/pythran/pythonic/numpy/linalg/matrix_power.hpp
new file mode 100644
index 00000000000..7c76b77df28
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/linalg/matrix_power.hpp
@@ -0,0 +1,62 @@
+#ifndef PYTHONIC_NUMPY_LINALG_MATRIX_POWER_HPP
+#define PYTHONIC_NUMPY_LINALG_MATRIX_POWER_HPP
+
+#include "pythonic/include/numpy/linalg/matrix_power.hpp"
+
+#include "pythonic/numpy/array.hpp"
+#include "pythonic/numpy/asarray.hpp"
+#include "pythonic/numpy/identity.hpp"
+#include "pythonic/numpy/dot.hpp"
+
+#include "pythonic/builtins/NotImplementedError.hpp"
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace linalg
+ {
+
+ namespace details
+ {
+
+ template <class E>
+ E fast_pow(E const &base, long n)
+ {
+ if (n == 1)
+ return base;
+ if (n == 2)
+ return numpy::functor::dot{}(base, base);
+ if (n == 3) {
+ auto tmp = numpy::functor::dot{}(base, base);
+ return numpy::functor::dot{}(tmp, base);
+ }
+ // starting from here, we know for sure that tmp will point to newly
+ // allocated memory
+ // this is used to optimize in-place dot computation in the odd case
+ auto tmp = fast_pow(base, n / 2);
+ if (n & 1) {
+ auto next = numpy::functor::dot{}(tmp, tmp);
+ return numpy::functor::dot{}(base, next, tmp);
+ } else {
+ return numpy::functor::dot{}(tmp, tmp);
+ }
+ }
+ }
+
+ template <class E>
+ auto matrix_power(E const &expr, long n)
+ -> decltype(numpy::functor::array{}(expr))
+ {
+ if (n == 0)
+ return numpy::functor::identity{}(expr.template shape<0>(),
+ types::dtype_t<typename E::dtype>{});
+ if (n > 0) {
+ auto base = numpy::functor::asarray{}(expr);
+ return details::fast_pow(base, n);
+ }
+ throw pythonic::builtins::NotImplementedError("negative power");
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/linspace.hpp b/contrib/python/pythran/pythran/pythonic/numpy/linspace.hpp
new file mode 100644
index 00000000000..9d08a984266
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/linspace.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_NUMPY_LINSPACE_HPP
+#define PYTHONIC_NUMPY_LINSPACE_HPP
+
+#include "pythonic/include/numpy/linspace.hpp"
+
+#include "pythonic/numpy/arange.hpp"
+#include "pythonic/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class dtype>
+ types::ndarray<typename dtype::type, types::pshape<long>>
+ linspace(double start, double stop, long num, bool endpoint, bool retstep,
+ dtype d)
+ {
+ assert(!retstep && "retstep not supported");
+ double step = (stop - start) / (num - (endpoint ? 1 : 0));
+ if (std::is_integral<typename dtype::type>::value)
+ return asarray(arange(start, stop + (endpoint ? step * .5 : 0), step), d);
+ else
+ return arange(start, stop + (endpoint ? step * .5 : 0), step, d);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/log10.hpp b/contrib/python/pythran/pythran/pythonic/numpy/log10.hpp
new file mode 100644
index 00000000000..6548a7bc39e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/log10.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_NUMPY_LOG10_HPP
+#define PYTHONIC_NUMPY_LOG10_HPP
+
+#include "pythonic/include/numpy/log10.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME log10
+#define NUMPY_NARY_FUNC_SYM xsimd::log10
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/log1p.hpp b/contrib/python/pythran/pythran/pythonic/numpy/log1p.hpp
new file mode 100644
index 00000000000..68622caf83f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/log1p.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_NUMPY_LOG1P_HPP
+#define PYTHONIC_NUMPY_LOG1P_HPP
+
+#include "pythonic/include/numpy/log1p.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME log1p
+#define NUMPY_NARY_FUNC_SYM xsimd::log1p
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/log2.hpp b/contrib/python/pythran/pythran/pythonic/numpy/log2.hpp
new file mode 100644
index 00000000000..ff251e7766d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/log2.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_NUMPY_LOG2_HPP
+#define PYTHONIC_NUMPY_LOG2_HPP
+
+#include "pythonic/include/numpy/log2.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME log2
+#define NUMPY_NARY_FUNC_SYM xsimd::log2
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/logaddexp.hpp b/contrib/python/pythran/pythran/pythonic/numpy/logaddexp.hpp
new file mode 100644
index 00000000000..6db4baa5d46
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/logaddexp.hpp
@@ -0,0 +1,32 @@
+#ifndef PYTHONIC_NUMPY_LOGADDEXP_HPP
+#define PYTHONIC_NUMPY_LOGADDEXP_HPP
+
+#include "pythonic/include/numpy/logaddexp.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/numpy/log.hpp"
+#include "pythonic/numpy/exp.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T0, class T1>
+ auto logaddexp(T0 const &t0, T1 const &t1)
+ -> decltype(functor::log{}(functor::exp{}(t0) + functor::exp{}(t1)))
+ {
+ return functor::log{}(functor::exp{}(t0) + functor::exp{}(t1));
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME logaddexp
+#define NUMPY_NARY_FUNC_SYM wrapper::logaddexp
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/logaddexp/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/logaddexp/accumulate.hpp
new file mode 100644
index 00000000000..703ff2c5cce
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/logaddexp/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_LOGADDEXP_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_LOGADDEXP_ACCUMULATE_HPP
+
+#define UFUNC_NAME logaddexp
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/logaddexp2.hpp b/contrib/python/pythran/pythran/pythonic/numpy/logaddexp2.hpp
new file mode 100644
index 00000000000..5a210edf6ac
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/logaddexp2.hpp
@@ -0,0 +1,36 @@
+#ifndef PYTHONIC_NUMPY_LOGADDEXP2_HPP
+#define PYTHONIC_NUMPY_LOGADDEXP2_HPP
+
+#include "pythonic/include/numpy/logaddexp2.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+#include "pythonic/numpy/log2.hpp"
+#include "pythonic/numpy/power.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T0, class T1>
+ auto logaddexp2(T0 const &t0, T1 const &t1)
+ -> decltype(functor::log2{}(functor::power{}(T0(2), t0) +
+ functor::power{}(T1(2), t1)))
+ {
+ return functor::log2{}(functor::power{}(T0(2), t0) +
+ functor::power{}(T1(2), t1));
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME logaddexp2
+#define NUMPY_NARY_FUNC_SYM wrapper::logaddexp2
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/logaddexp2/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/logaddexp2/accumulate.hpp
new file mode 100644
index 00000000000..3a2d01028ef
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/logaddexp2/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_LOGADDEXP2_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_LOGADDEXP2_ACCUMULATE_HPP
+
+#define UFUNC_NAME logaddexp2
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/logical_and.hpp b/contrib/python/pythran/pythran/pythonic/numpy/logical_and.hpp
new file mode 100644
index 00000000000..c9b92e52fdc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/logical_and.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_NUMPY_LOGICALAND_HPP
+#define PYTHONIC_NUMPY_LOGICALAND_HPP
+
+#include "pythonic/include/numpy/logical_and.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace wrapper
+ {
+ template <class T0, class T1>
+ auto logical_and(T0 const &t0, T1 const &t1) -> decltype(t0 &&t1)
+ {
+ return t0 && t1;
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME logical_and
+#define NUMPY_NARY_FUNC_SYM wrapper::logical_and
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/logical_and/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/logical_and/accumulate.hpp
new file mode 100644
index 00000000000..dfdb143e978
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/logical_and/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_LOGICAL_AND_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_LOGICAL_AND_ACCUMULATE_HPP
+
+#define UFUNC_NAME logical_and
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/logical_not.hpp b/contrib/python/pythran/pythran/pythonic/numpy/logical_not.hpp
new file mode 100644
index 00000000000..00b1e63a282
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/logical_not.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_NUMPY_LOGICALNOT_HPP
+#define PYTHONIC_NUMPY_LOGICALNOT_HPP
+
+#include "pythonic/include/numpy/logical_not.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/operator_/not_.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME logical_not
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::not_
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/logical_or.hpp b/contrib/python/pythran/pythran/pythonic/numpy/logical_or.hpp
new file mode 100644
index 00000000000..5c8614bbbde
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/logical_or.hpp
@@ -0,0 +1,30 @@
+#ifndef PYTHONIC_NUMPY_LOGICALOR_HPP
+#define PYTHONIC_NUMPY_LOGICALOR_HPP
+
+#include "pythonic/include/numpy/logical_or.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T0, class T1>
+ auto logical_or(T0 const &t0, T1 const &t1) -> decltype(t0 || t1)
+ {
+ return t0 || t1;
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME logical_or
+#define NUMPY_NARY_FUNC_SYM wrapper::logical_or
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/logical_or/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/logical_or/accumulate.hpp
new file mode 100644
index 00000000000..15e08cafa73
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/logical_or/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_LOGICAL_OR_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_LOGICAL_OR_ACCUMULATE_HPP
+
+#define UFUNC_NAME logical_or
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/logical_xor.hpp b/contrib/python/pythran/pythran/pythonic/numpy/logical_xor.hpp
new file mode 100644
index 00000000000..a01ac9d30e2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/logical_xor.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_NUMPY_LOGICALXOR_HPP
+#define PYTHONIC_NUMPY_LOGICALXOR_HPP
+
+#include "pythonic/include/numpy/logical_xor.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T0, class T1>
+ auto logical_xor(T0 const &t0, T1 const &t1)
+ -> decltype((t0 && !t1) || (t1 && !t0))
+ {
+ return (t0 && !t1) || (t1 && !t0);
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME logical_xor
+#define NUMPY_NARY_FUNC_SYM wrapper::logical_xor
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/logical_xor/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/logical_xor/accumulate.hpp
new file mode 100644
index 00000000000..5643d58d30b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/logical_xor/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_LOGICAL_XOR_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_LOGICAL_XOR_ACCUMULATE_HPP
+
+#define UFUNC_NAME logical_xor
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/logspace.hpp b/contrib/python/pythran/pythran/pythonic/numpy/logspace.hpp
new file mode 100644
index 00000000000..a9e9a5e656d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/logspace.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_NUMPY_LOGSPACE_HPP
+#define PYTHONIC_NUMPY_LOGSPACE_HPP
+
+#include "pythonic/include/numpy/logspace.hpp"
+
+#include "pythonic/numpy/linspace.hpp"
+#include "pythonic/numpy/power.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ auto logspace(double start, double stop, long num, bool endpoint, double base)
+ -> decltype(functor::power()(base, functor::linspace()(start, stop, num,
+ endpoint)))
+ {
+ return functor::power()(base,
+ functor::linspace()(start, stop, num, endpoint));
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/longlong.hpp b/contrib/python/pythran/pythran/pythonic/numpy/longlong.hpp
new file mode 100644
index 00000000000..1fe2865e2bc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/longlong.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_NUMPY_LONGLONG_HPP
+#define PYTHONIC_NUMPY_LONGLONG_HPP
+
+#include "pythonic/include/numpy/longlong.hpp"
+
+#include "pythonic/types/numpy_op_helper.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/meta.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ inline long long longlong()
+ {
+ return {};
+ }
+
+ template <class V>
+ long long longlong(V v)
+ {
+ return v;
+ }
+ } // namespace details
+
+#define NUMPY_NARY_FUNC_NAME longlong
+#define NUMPY_NARY_FUNC_SYM details::longlong
+#include "pythonic/types/numpy_nary_expr.hpp"
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/maximum/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/maximum/accumulate.hpp
new file mode 100644
index 00000000000..67c1614937b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/maximum/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_MAXIMUM_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_MAXIMUM_ACCUMULATE_HPP
+
+#define UFUNC_NAME maximum
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/maximum/reduce.hpp b/contrib/python/pythran/pythran/pythonic/numpy/maximum/reduce.hpp
new file mode 100644
index 00000000000..64a0b032718
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/maximum/reduce.hpp
@@ -0,0 +1,11 @@
+#ifndef PYTHONIC_NUMPY_MAXIMUM_REDUCE_HPP
+#define PYTHONIC_NUMPY_MAXIMUM_REDUCE_HPP
+
+#define UFUNC_NAME maximum
+#define UFUNC_INAME imax
+#include "pythonic/include/numpy/maximum/reduce.hpp"
+#include "pythonic/numpy/ufunc_reduce.hpp"
+#undef UFUNC_NAME
+#undef UFUNC_INAME
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/mean.hpp b/contrib/python/pythran/pythran/pythonic/numpy/mean.hpp
new file mode 100644
index 00000000000..5553f9e228f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/mean.hpp
@@ -0,0 +1,54 @@
+#ifndef PYTHONIC_NUMPY_MEAN_HPP
+#define PYTHONIC_NUMPY_MEAN_HPP
+
+#include "pythonic/include/numpy/mean.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/numpy/asarray.hpp"
+#include "pythonic/numpy/expand_dims.hpp"
+#include "pythonic/numpy/sum.hpp"
+#include "pythonic/builtins/None.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class E, class dtype>
+ auto mean(E const &expr, types::none_type axis, dtype d, types::none_type out,
+ types::false_immediate keepdims)
+ -> decltype(sum(expr, axis, d) /
+ details::dtype_or_double<dtype>(expr.flat_size()))
+ {
+ return sum(expr, axis, d) /
+ details::dtype_or_double<dtype>(expr.flat_size());
+ }
+
+ template <class E, class dtype>
+ auto mean(E const &expr, long axis, dtype d, types::none_type out,
+ types::false_immediate keepdims) -> decltype(sum(expr, axis, d))
+ {
+ return sum(expr, axis, d) /=
+ details::dtype_or_double<dtype>(sutils::getshape(expr)[axis]);
+ }
+
+ template <class E, class dtype>
+ types::ndarray<details::dtype_or_double<dtype>,
+ typename details::make_scalar_pshape<E::value>::type>
+ mean(E const &expr, types::none_type axis, dtype d, types::none_type out,
+ types::true_immediate keep_dims)
+ {
+ return {typename details::make_scalar_pshape<E::value>::type(),
+ mean(expr, axis, d, out)};
+ }
+
+ template <class E, class dtype>
+ auto mean(E const &expr, long axis, dtype d, types::none_type out,
+ types::true_immediate keepdims)
+ -> decltype(expand_dims(mean(expr, axis, d), axis))
+ {
+ return expand_dims(mean(expr, axis, d), axis);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/minimum/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/minimum/accumulate.hpp
new file mode 100644
index 00000000000..09f6eef8668
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/minimum/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_MINIMUM_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_MINIMUM_ACCUMULATE_HPP
+
+#define UFUNC_NAME minimum
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/minimum/reduce.hpp b/contrib/python/pythran/pythran/pythonic/numpy/minimum/reduce.hpp
new file mode 100644
index 00000000000..8856db48439
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/minimum/reduce.hpp
@@ -0,0 +1,11 @@
+#ifndef PYTHONIC_NUMPY_MINIMUM_REDUCE_HPP
+#define PYTHONIC_NUMPY_MINIMUM_REDUCE_HPP
+
+#define UFUNC_NAME minimum
+#define UFUNC_INAME imin
+#include "pythonic/include/numpy/minimum/reduce.hpp"
+#include "pythonic/numpy/ufunc_reduce.hpp"
+#undef UFUNC_NAME
+#undef UFUNC_INAME
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/mod/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/mod/accumulate.hpp
new file mode 100644
index 00000000000..f401ef4daa5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/mod/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_MOD_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_MOD_ACCUMULATE_HPP
+
+#define UFUNC_NAME mod
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/multiply.hpp b/contrib/python/pythran/pythran/pythonic/numpy/multiply.hpp
new file mode 100644
index 00000000000..a62644f9c38
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/multiply.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_NUMPY_MULTIPLY_HPP
+#define PYTHONIC_NUMPY_MULTIPLY_HPP
+
+#include "pythonic/include/numpy/multiply.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/operator_/mul.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME multiply
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::mul
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/multiply/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/multiply/accumulate.hpp
new file mode 100644
index 00000000000..d093247a2ac
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/multiply/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_MULTIPLY_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_MULTIPLY_ACCUMULATE_HPP
+
+#define UFUNC_NAME multiply
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/multiply/reduce.hpp b/contrib/python/pythran/pythran/pythonic/numpy/multiply/reduce.hpp
new file mode 100644
index 00000000000..8f9fea61294
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/multiply/reduce.hpp
@@ -0,0 +1,11 @@
+#ifndef PYTHONIC_NUMPY_MULTIPLY_REDUCE_HPP
+#define PYTHONIC_NUMPY_MULTIPLY_REDUCE_HPP
+
+#define UFUNC_NAME multiply
+#define UFUNC_INAME imul
+#include "pythonic/include/numpy/multiply/reduce.hpp"
+#include "pythonic/numpy/ufunc_reduce.hpp"
+#undef UFUNC_NAME
+#undef UFUNC_INAME
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/nan.hpp b/contrib/python/pythran/pythran/pythonic/numpy/nan.hpp
new file mode 100644
index 00000000000..8e10a686cdc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/nan.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_NUMPY_NAN_HPP
+#define PYTHONIC_NUMPY_NAN_HPP
+
+#include "pythonic/include/numpy/nan.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/nan_to_num.hpp b/contrib/python/pythran/pythran/pythonic/numpy/nan_to_num.hpp
new file mode 100644
index 00000000000..0a4bbe2ba44
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/nan_to_num.hpp
@@ -0,0 +1,42 @@
+#ifndef PYTHONIC_NUMPY_NANTONUM_HPP
+#define PYTHONIC_NUMPY_NANTONUM_HPP
+
+#include "pythonic/include/numpy/nan_to_num.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/numpy/isinf.hpp"
+#include "pythonic/numpy/isnan.hpp"
+
+#include <limits>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace wrapper
+ {
+ template <class I>
+ I nan_to_num(I const &a)
+ {
+ if (functor::isinf{}(a)) {
+ if (a >= 0)
+ return std::numeric_limits<I>::max();
+ else
+ return std::numeric_limits<I>::lowest();
+ } else if (functor::isnan{}(a))
+ return 0;
+ else
+ return a;
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME nan_to_num
+#define NUMPY_NARY_FUNC_SYM wrapper::nan_to_num
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/nanargmax.hpp b/contrib/python/pythran/pythran/pythonic/numpy/nanargmax.hpp
new file mode 100644
index 00000000000..a64f8cbb319
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/nanargmax.hpp
@@ -0,0 +1,56 @@
+#ifndef PYTHONIC_NUMPY_NANARGMAX_HPP
+#define PYTHONIC_NUMPY_NANARGMAX_HPP
+
+#include "pythonic/include/numpy/nanargmax.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/builtins/ValueError.hpp"
+#include "pythonic/numpy/isnan.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace
+ {
+ template <class E, class F>
+ void _nanargmax(E begin, E end, F &max, long &index, long &where,
+ utils::int_<1>)
+ {
+ for (; begin != end; ++begin, ++index) {
+ auto curr = *begin;
+ if (!functor::isnan()(curr) && curr > max) {
+ max = curr;
+ where = index;
+ }
+ }
+ }
+
+ template <class E, class F, size_t N>
+ void _nanargmax(E begin, E end, F &max, long &index, long &where,
+ utils::int_<N>)
+ {
+ for (; begin != end; ++begin)
+ _nanargmax((*begin).begin(), (*begin).end(), max, index, where,
+ utils::int_<N - 1>());
+ }
+ }
+
+ template <class E>
+ long nanargmax(E const &expr)
+ {
+ typename E::dtype max = -std::numeric_limits<typename E::dtype>::infinity();
+ long where = -1;
+ long index = 0;
+ _nanargmax(expr.begin(), expr.end(), max, index, where,
+ utils::int_<E::value>());
+ if (where >= 0)
+ return where;
+ else
+ throw types::ValueError("empty sequence");
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/nanargmin.hpp b/contrib/python/pythran/pythran/pythonic/numpy/nanargmin.hpp
new file mode 100644
index 00000000000..3ea1be21299
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/nanargmin.hpp
@@ -0,0 +1,57 @@
+#ifndef PYTHONIC_NUMPY_NANARGMIN_HPP
+#define PYTHONIC_NUMPY_NANARGMIN_HPP
+
+#include "pythonic/include/numpy/nanargmin.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/builtins/ValueError.hpp"
+#include "pythonic/numpy/isnan.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace
+ {
+ template <class E, class F>
+ void _nanargmin(E begin, E end, F &min, long &index, long &where,
+ utils::int_<1>)
+ {
+ for (; begin != end; ++begin, ++index) {
+ auto curr = *begin;
+ if (!functor::isnan()(curr) && curr < min) {
+ min = curr;
+ where = index;
+ }
+ }
+ }
+
+ template <class E, class F, size_t N>
+ void _nanargmin(E begin, E end, F &min, long &index, long &where,
+ utils::int_<N>)
+ {
+ for (; begin != end; ++begin)
+ _nanargmin((*begin).begin(), (*begin).end(), min, index, where,
+ utils::int_<N - 1>());
+ }
+ }
+
+ template <class E>
+ long nanargmin(E const &expr)
+ {
+ typename E::dtype min = std::numeric_limits<typename E::dtype>::infinity();
+ long where = -1;
+ long index = 0;
+ _nanargmin(expr.begin(), expr.end(), min, index, where,
+ utils::int_<E::value>());
+ if (where >= 0)
+ return where;
+ else
+ throw types::ValueError("empty sequence");
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/nanmax.hpp b/contrib/python/pythran/pythran/pythonic/numpy/nanmax.hpp
new file mode 100644
index 00000000000..618fba3ae58
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/nanmax.hpp
@@ -0,0 +1,55 @@
+#ifndef PYTHONIC_NUMPY_NANMAX_HPP
+#define PYTHONIC_NUMPY_NANMAX_HPP
+
+#include "pythonic/include/numpy/nanmax.hpp"
+
+#include "pythonic/builtins/ValueError.hpp"
+#include "pythonic/numpy/isnan.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace
+ {
+ template <class E, class F>
+ bool _nanmax(E begin, E end, F &max, utils::int_<1>)
+ {
+ bool found = false;
+ for (; begin != end; ++begin) {
+ auto curr = *begin;
+ if (!functor::isnan()(curr) && curr >= max) {
+ max = curr;
+ found = true;
+ }
+ }
+ return found;
+ }
+
+ template <class E, class F, size_t N>
+ bool _nanmax(E begin, E end, F &max, utils::int_<N>)
+ {
+ bool found = false;
+ for (; begin != end; ++begin)
+ found |= _nanmax((*begin).begin(), (*begin).end(), max,
+ utils::int_<N - 1>());
+ return found;
+ }
+ }
+
+ template <class E>
+ typename E::dtype nanmax(E const &expr)
+ {
+ bool found = false;
+ typename E::dtype max = std::numeric_limits<typename E::dtype>::lowest();
+ found = _nanmax(expr.begin(), expr.end(), max, utils::int_<E::value>());
+ if (!found)
+ max = std::numeric_limits<typename E::dtype>::quiet_NaN();
+ return max;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/nanmin.hpp b/contrib/python/pythran/pythran/pythonic/numpy/nanmin.hpp
new file mode 100644
index 00000000000..f80f98086e2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/nanmin.hpp
@@ -0,0 +1,55 @@
+#ifndef PYTHONIC_NUMPY_NANMIN_HPP
+#define PYTHONIC_NUMPY_NANMIN_HPP
+
+#include "pythonic/include/numpy/nanmin.hpp"
+
+#include "pythonic/builtins/ValueError.hpp"
+#include "pythonic/numpy/isnan.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace
+ {
+ template <class E, class F>
+ bool _nanmin(E begin, E end, F &min, utils::int_<1>)
+ {
+ bool found = false;
+ for (; begin != end; ++begin) {
+ auto curr = *begin;
+ if (!functor::isnan()(curr) && curr <= min) {
+ min = curr;
+ found = true;
+ }
+ }
+ return found;
+ }
+
+ template <class E, class F, size_t N>
+ bool _nanmin(E begin, E end, F &min, utils::int_<N>)
+ {
+ bool found = false;
+ for (; begin != end; ++begin)
+ found |= _nanmin((*begin).begin(), (*begin).end(), min,
+ utils::int_<N - 1>());
+ return found;
+ }
+ }
+
+ template <class E>
+ typename E::dtype nanmin(E const &expr)
+ {
+ bool found = false;
+ typename E::dtype min = std::numeric_limits<typename E::dtype>::max();
+ found = _nanmin(expr.begin(), expr.end(), min, utils::int_<E::value>());
+ if (!found)
+ min = std::numeric_limits<typename E::dtype>::quiet_NaN();
+ return min;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/nansum.hpp b/contrib/python/pythran/pythran/pythonic/numpy/nansum.hpp
new file mode 100644
index 00000000000..65b2e1508bf
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/nansum.hpp
@@ -0,0 +1,40 @@
+#ifndef PYTHONIC_NUMPY_NANSUM_HPP
+#define PYTHONIC_NUMPY_NANSUM_HPP
+
+#include "pythonic/include/numpy/nansum.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/numpy/isnan.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E, class F>
+ void _nansum(E begin, E end, F &sum, utils::int_<1>)
+ {
+ for (; begin != end; ++begin) {
+ auto curr = *begin;
+ if (!functor::isnan()(curr))
+ sum += curr;
+ }
+ }
+ template <class E, class F, size_t N>
+ void _nansum(E begin, E end, F &sum, utils::int_<N>)
+ {
+ for (; begin != end; ++begin)
+ _nansum((*begin).begin(), (*begin).end(), sum, utils::int_<N - 1>());
+ }
+
+ template <class E>
+ typename E::dtype nansum(E const &expr)
+ {
+ typename E::dtype s = 0;
+ _nansum(expr.begin(), expr.end(), s, utils::int_<E::value>());
+ return s;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ndarray.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ndarray.hpp
new file mode 100644
index 00000000000..663cc823d3a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ndarray.hpp
@@ -0,0 +1,38 @@
+#ifndef PYTHONIC_NUMPY_NDARRAY_HPP
+#define PYTHONIC_NUMPY_NDARRAY_HPP
+
+#include "pythonic/include/numpy/ndarray.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/nested_container.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class pS, class dtype>
+ types::ndarray<typename dtype::type, sutils::shape_t<pS>>
+ ndarray(pS const &shape, dtype)
+ {
+ return {(sutils::shape_t<pS>)shape, builtins::None};
+ }
+
+ template <class dtype>
+ types::ndarray<typename dtype::type, types::pshape<long>> ndarray(long size,
+ dtype d)
+ {
+ return ndarray(types::pshape<long>(size), d);
+ }
+
+ template <long N, class dtype>
+ types::ndarray<typename dtype::type,
+ types::pshape<std::integral_constant<long, N>>>
+ ndarray(std::integral_constant<long, N>, dtype d)
+ {
+ return ndarray(types::pshape<std::integral_constant<long, N>>({}), d);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ndarray/astype.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ndarray/astype.hpp
new file mode 100644
index 00000000000..d054f80a683
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ndarray/astype.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_NUMPY_NDARRAY_ASTYPE_HPP
+#define PYTHONIC_NUMPY_NDARRAY_ASTYPE_HPP
+
+#include "pythonic/include/numpy/ndarray/astype.hpp"
+#include "pythonic/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace ndarray
+ {
+
+ template <class E, class dtype>
+ auto astype(E &&e, dtype d) -> decltype(asarray(std::forward<E>(e), d))
+ {
+ return asarray(std::forward<E>(e), d);
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ndarray/flatten.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ndarray/flatten.hpp
new file mode 100644
index 00000000000..6e0afe6fb3f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ndarray/flatten.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_NUMPY_NDARRAY_FLATTEN_HPP
+#define PYTHONIC_NUMPY_NDARRAY_FLATTEN_HPP
+
+#include "pythonic/include/numpy/ndarray/flatten.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace ndarray
+ {
+ template <class T, class pS>
+ types::ndarray<T, types::pshape<long>>
+ flatten(types::ndarray<T, pS> const &a)
+ {
+ return {a.mem, types::pshape<long>{a.flat_size()}};
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(flatten);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ndarray/item.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ndarray/item.hpp
new file mode 100644
index 00000000000..cb2ba3626be
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ndarray/item.hpp
@@ -0,0 +1,43 @@
+#ifndef PYTHONIC_NUMPY_NDARRAY_ITEM_HPP
+#define PYTHONIC_NUMPY_NDARRAY_ITEM_HPP
+
+#include "pythonic/include/numpy/ndarray/item.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace ndarray
+ {
+
+ template <class T, class pS>
+ T item(types::ndarray<T, pS> const &expr, long i)
+ {
+ if (i < 0)
+ i += expr.flat_size();
+ return *(expr.fbegin() + i);
+ }
+
+ template <class E, size_t N>
+ auto item(E &&expr, types::array<long, N> const &i) -> decltype(expr[i])
+ {
+ return expr[i];
+ }
+
+ // only for compatibility purpose, very bad impl
+ template <class E>
+ typename std::decay<E>::type::dtype item(E &&expr, long i)
+ {
+ if (i < 0)
+ i += expr.flat_size();
+ return asarray(std::forward<E>(expr)).flat()[i];
+ }
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ndarray/reshape.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ndarray/reshape.hpp
new file mode 100644
index 00000000000..b8b6cc68d38
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ndarray/reshape.hpp
@@ -0,0 +1,99 @@
+#ifndef PYTHONIC_NUMPY_NDARRAY_RESHAPE_HPP
+#define PYTHONIC_NUMPY_NDARRAY_RESHAPE_HPP
+
+#include "pythonic/include/numpy/ndarray/reshape.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_conversion.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/builtins/ValueError.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace ndarray
+ {
+ namespace misc
+ {
+ template <class P, size_t... Is>
+ void set(P &p, long i, long v, utils::index_sequence<Is...>)
+ {
+ (void)std::initializer_list<bool>{
+ (i == Is && (sutils::assign(std::get<Is>(p), v), true))...};
+ }
+ }
+ template <class T, class pS, class NpS>
+ typename std::enable_if<!std::is_integral<NpS>::value,
+ types::ndarray<T, NpS>>::type
+ reshape(types::ndarray<T, pS> const &expr, NpS const &new_shape)
+ {
+ long where = sutils::sfind(
+ new_shape, -1,
+ std::integral_constant<size_t, std::tuple_size<NpS>::value>(),
+ [](long a, long b) { return a <= b; });
+ long next = sutils::sfind(new_shape, -1, where,
+ [](long a, long b) { return a <= b; });
+ if (next >= 0) {
+ throw pythonic::types::ValueError(
+ "Reshape: can only specify one unknown dimension");
+ }
+
+ if (where >= 0) {
+ auto auto_shape = new_shape;
+ misc::set(auto_shape, where,
+ expr.flat_size() / -sutils::sprod(new_shape),
+ utils::make_index_sequence<std::tuple_size<NpS>::value>());
+ return expr.reshape(auto_shape);
+ } else {
+ auto nshape = sutils::sprod(new_shape);
+ auto n = expr.flat_size();
+ if (n < nshape) {
+ types::ndarray<T, NpS> out(new_shape, builtins::None);
+ auto iter = std::copy(expr.fbegin(), expr.fend(), out.fbegin());
+ for (long i = 1; i < nshape / n; ++i)
+ iter = std::copy(out.fbegin(), out.fbegin() + n, iter);
+ std::copy(out.fbegin(), out.fbegin() + nshape % n, iter);
+ return out;
+ } else {
+ return expr.reshape(new_shape);
+ }
+ }
+ }
+ template <class T, class pS, class NpS>
+ typename std::enable_if<std::is_integral<NpS>::value,
+ types::ndarray<T, types::pshape<long>>>::type
+ reshape(types::ndarray<T, pS> const &expr, NpS const &new_shape)
+ {
+ auto n = expr.flat_size();
+ if (new_shape <= -1) {
+ return expr.reshape(types::pshape<long>(n));
+ }
+ if (n < new_shape) {
+ types::ndarray<T, types::pshape<long>> out(
+ types::pshape<long>{new_shape}, builtins::None);
+ auto iter = std::copy(expr.fbegin(), expr.fend(), out.fbegin());
+ for (long i = 1; i < new_shape / n; ++i)
+ iter = std::copy(out.fbegin(), out.fbegin() + n, iter);
+ std::copy(out.fbegin(), out.fbegin() + new_shape % n, iter);
+ return out;
+ } else {
+ return expr.reshape(types::pshape<long>(new_shape));
+ }
+ }
+
+ template <class T, class pS, class S0, class S1, class... S>
+ auto reshape(types::ndarray<T, pS> const &expr, S0 i0, S1 i1,
+ S const &... indices)
+ -> decltype(reshape(expr,
+ types::pshape<S0, S1, S...>{i0, i1, indices...}))
+ {
+ return reshape(expr, types::pshape<S0, S1, S...>{i0, i1, indices...});
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(reshape);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ndarray/tofile.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ndarray/tofile.hpp
new file mode 100644
index 00000000000..8a10719f732
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ndarray/tofile.hpp
@@ -0,0 +1,43 @@
+#ifndef PYTHONIC_NUMPY_NDARRAY_TOFILE_HPP
+#define PYTHONIC_NUMPY_NDARRAY_TOFILE_HPP
+
+#include "pythonic/include/numpy/ndarray/tofile.hpp"
+#include "pythonic/builtins/FileNotFoundError.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+#include <fstream>
+#include <limits>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace ndarray
+ {
+ template <class T, class pS>
+ void tofile(types::ndarray<T, pS> const &expr, types::str const &file_name,
+ types::str const &sep, types::str const &format)
+ {
+ if (sep.size() != 0)
+ throw types::NotImplementedError(
+ "Sep input is not implemented yet, should be left empty");
+ if (format.size() != 0)
+ throw types::NotImplementedError(
+ "Format input is not implemented yet, should be left empty");
+ std::ofstream fs;
+ fs.open(file_name.c_str(), std::ofstream::out | std::ofstream::binary);
+ if (fs.rdstate() != std::ofstream::goodbit) {
+ throw types::FileNotFoundError("Could not open file " + file_name);
+ }
+ fs.write((char *)expr.buffer, sizeof(T) * expr.flat_size());
+ }
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(tofile);
+ }
+}
+
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ndarray/tolist.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ndarray/tolist.hpp
new file mode 100644
index 00000000000..e7b07052f0e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ndarray/tolist.hpp
@@ -0,0 +1,43 @@
+#ifndef PYTHONIC_NUMPY_NDARRAY_TOLIST_HPP
+#define PYTHONIC_NUMPY_NDARRAY_TOLIST_HPP
+
+#include "pythonic/include/numpy/ndarray/tolist.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_conversion.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace ndarray
+ {
+
+ template <class T, class pS>
+ typename std::enable_if<std::tuple_size<pS>::value == 1,
+ types::list<T>>::type
+ tolist(types::ndarray<T, pS> const &expr)
+ {
+ return {expr.fbegin(), expr.fend()};
+ }
+
+ template <class T, class pS>
+ typename std::enable_if<
+ std::tuple_size<pS>::value != 1,
+ typename tolist_type<T, std::tuple_size<pS>::value>::type>::type
+ tolist(types::ndarray<T, pS> const &expr)
+ {
+ typename tolist_type<T, std::tuple_size<pS>::value>::type out(0);
+ for (auto const &elts : expr)
+ out.push_back(tolist(elts));
+ return out;
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(tolist);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ndarray/tostring.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ndarray/tostring.hpp
new file mode 100644
index 00000000000..bb04b615df8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ndarray/tostring.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_NUMPY_NDARRAY_TOSTRING_HPP
+#define PYTHONIC_NUMPY_NDARRAY_TOSTRING_HPP
+
+#include "pythonic/include/numpy/ndarray/tostring.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_conversion.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/str.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace ndarray
+ {
+ template <class T, class pS>
+ types::str tostring(types::ndarray<T, pS> const &expr)
+ {
+ return types::str(reinterpret_cast<const char *>(expr.buffer),
+ expr.flat_size() * sizeof(T));
+ }
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(tostring);
+ }
+}
+PYTHONIC_NS_END
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ndarray/view.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ndarray/view.hpp
new file mode 100644
index 00000000000..61068cb1114
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ndarray/view.hpp
@@ -0,0 +1,30 @@
+#ifndef PYTHONIC_NUMPY_NDARRAY_VIEW_HPP
+#define PYTHONIC_NUMPY_NDARRAY_VIEW_HPP
+
+#include "pythonic/include/numpy/ndarray/view.hpp"
+#include "pythonic/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace ndarray
+ {
+ template <class E>
+ auto view(E &&e) -> decltype(std::forward<E>(e))
+ {
+ return std::forward<E>(e);
+ }
+
+ template <class E, class dtype>
+ auto view(E &&e, dtype d)
+ -> decltype(std::forward<E>(e).template recast<typename dtype::type>())
+ {
+ return std::forward<E>(e).template recast<typename dtype::type>();
+ }
+
+ } // namespace ndarray
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ndenumerate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ndenumerate.hpp
new file mode 100644
index 00000000000..150edfda89c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ndenumerate.hpp
@@ -0,0 +1,115 @@
+#ifndef PYTHONIC_NUMPY_NDENUMERATE_HPP
+#define PYTHONIC_NUMPY_NDENUMERATE_HPP
+
+#include "pythonic/include/numpy/ndenumerate.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ ndenumerate_iterator<E>::ndenumerate_iterator()
+ {
+ }
+
+ template <class E>
+ ndenumerate_iterator<E>::ndenumerate_iterator(E const &expr, long first)
+ : index(first), expr(expr), iter(expr.buffer)
+ {
+ }
+
+ template <class E>
+ std::tuple<types::array<long, E::value>, typename E::dtype>
+ ndenumerate_iterator<E>::operator*() const
+ {
+ types::array<long, E::value> out;
+ auto shape = sutils::getshape(expr);
+ long mult = 1;
+ for (long j = E::value - 1; j > 0; j--) {
+ out[j] = (index / mult) % shape[j];
+ mult *= shape[j];
+ }
+ out[0] = index / mult;
+ return std::tuple<types::array<long, E::value>, typename E::dtype>{out,
+ *iter};
+ }
+
+ template <class E>
+ ndenumerate_iterator<E> &ndenumerate_iterator<E>::operator++()
+ {
+ ++index, ++iter;
+ return *this;
+ }
+
+ template <class E>
+ ndenumerate_iterator<E> &ndenumerate_iterator<E>::operator+=(long n)
+ {
+ index += n, iter += n;
+ return *this;
+ }
+
+ template <class E>
+ bool ndenumerate_iterator<E>::
+ operator!=(ndenumerate_iterator<E> const &other) const
+ {
+ return index != other.index;
+ }
+
+ template <class E>
+ bool ndenumerate_iterator<E>::
+ operator<(ndenumerate_iterator<E> const &other) const
+ {
+ return index < other.index;
+ }
+
+ template <class E>
+ long ndenumerate_iterator<E>::
+ operator-(ndenumerate_iterator<E> const &other) const
+ {
+ return index - other.index;
+ }
+
+ template <class E>
+ _ndenumerate<E>::_ndenumerate()
+ {
+ }
+
+ template <class E>
+ _ndenumerate<E>::_ndenumerate(E const &expr)
+ : ndenumerate_iterator<E>(expr, 0), expr(expr),
+ end_iter(expr, expr.flat_size())
+ {
+ }
+
+ template <class E>
+ typename _ndenumerate<E>::iterator &_ndenumerate<E>::begin()
+ {
+ return *this;
+ }
+
+ template <class E>
+ typename _ndenumerate<E>::iterator const &_ndenumerate<E>::begin() const
+ {
+ return *this;
+ }
+
+ template <class E>
+ typename _ndenumerate<E>::iterator _ndenumerate<E>::end() const
+ {
+ return end_iter;
+ }
+
+ template <class T, class pS>
+ _ndenumerate<types::ndarray<T, pS>>
+ ndenumerate(types::ndarray<T, pS> const &expr)
+ {
+ return {expr};
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(ndenumerate);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ndim.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ndim.hpp
new file mode 100644
index 00000000000..1455284a575
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ndim.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_NUMPY_NDIM_HPP
+#define PYTHONIC_NUMPY_NDIM_HPP
+
+#include "pythonic/include/numpy/ndim.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class E>
+ long ndim(E const &e)
+ {
+ return std::tuple_size<decltype(shape(e))>::value;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ndindex.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ndindex.hpp
new file mode 100644
index 00000000000..24010dc5b38
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ndindex.hpp
@@ -0,0 +1,121 @@
+#ifndef PYTHONIC_NUMPY_NDINDEX_HPP
+#define PYTHONIC_NUMPY_NDINDEX_HPP
+
+#include "pythonic/include/numpy/ndindex.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+#include <numeric>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <size_t N>
+ ndindex_iterator<N>::ndindex_iterator()
+ {
+ }
+
+ template <size_t N>
+ ndindex_iterator<N>::ndindex_iterator(types::array<long, N> const &shape,
+ long first)
+ : index(first), shape(shape)
+ {
+ }
+
+ template <size_t N>
+ types::array<long, N> ndindex_iterator<N>::operator*() const
+ {
+ types::array<long, N> out;
+ long mult = 1;
+ for (long j = N - 1; j > 0; j--) {
+ out[j] = (index / mult) % shape[j];
+ mult *= shape[j];
+ }
+ out[0] = index / mult;
+ return out;
+ }
+
+ template <size_t N>
+ ndindex_iterator<N> &ndindex_iterator<N>::operator++()
+ {
+ ++index;
+ return *this;
+ }
+
+ template <size_t N>
+ ndindex_iterator<N> &ndindex_iterator<N>::operator+=(long n)
+ {
+ index += n;
+ return *this;
+ }
+
+ template <size_t N>
+ bool ndindex_iterator<N>::operator!=(ndindex_iterator<N> const &other) const
+ {
+ return index != other.index;
+ }
+
+ template <size_t N>
+ bool ndindex_iterator<N>::operator<(ndindex_iterator<N> const &other) const
+ {
+ return index < other.index;
+ }
+
+ template <size_t N>
+ long ndindex_iterator<N>::operator-(ndindex_iterator<N> const &other) const
+ {
+ return index - other.index;
+ }
+
+ template <size_t N>
+ _ndindex<N>::_ndindex()
+ {
+ }
+
+ template <size_t N>
+ _ndindex<N>::_ndindex(types::array<long, N> const &shape)
+ : ndindex_iterator<N>(shape, 0), shape(shape),
+ end_iter(shape, std::accumulate(shape.begin(), shape.end(), 1L,
+ std::multiplies<long>()))
+ {
+ }
+
+ template <size_t N>
+ typename _ndindex<N>::iterator &_ndindex<N>::begin()
+ {
+ return *this;
+ }
+
+ template <size_t N>
+ typename _ndindex<N>::iterator const &_ndindex<N>::begin() const
+ {
+ return *this;
+ }
+
+ template <size_t N>
+ typename _ndindex<N>::iterator _ndindex<N>::end() const
+ {
+ return end_iter;
+ }
+
+ template <class... Types>
+ _ndindex<sizeof...(Types)> ndindex(Types... args)
+ {
+ return {types::make_tuple(args...)};
+ }
+
+ template <size_t N>
+ _ndindex<N> ndindex(types::array<long, N> const &args)
+ {
+ return {args};
+ }
+ template <class... Tys>
+ _ndindex<sizeof...(Tys)> ndindex(types::pshape<Tys...> const &args)
+ {
+ return {args};
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/negative.hpp b/contrib/python/pythran/pythran/pythonic/numpy/negative.hpp
new file mode 100644
index 00000000000..bce0f54d22e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/negative.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_NUMPY_NEGATIVE_HPP
+#define PYTHONIC_NUMPY_NEGATIVE_HPP
+
+#include "pythonic/include/numpy/negative.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/operator_/neg.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME negative
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::neg
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/negative/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/negative/accumulate.hpp
new file mode 100644
index 00000000000..7baa32acfdb
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/negative/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_NEGATIVE_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_NEGATIVE_ACCUMULATE_HPP
+
+#define UFUNC_NAME negative
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/newaxis.hpp b/contrib/python/pythran/pythran/pythonic/numpy/newaxis.hpp
new file mode 100644
index 00000000000..7d179265fc3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/newaxis.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_NUMPY_NEWAXIS_HPP
+#define PYTHONIC_NUMPY_NEWAXIS_HPP
+
+#include "pythonic/include/numpy/newaxis.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/nextafter.hpp b/contrib/python/pythran/pythran/pythonic/numpy/nextafter.hpp
new file mode 100644
index 00000000000..cb2406107fe
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/nextafter.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_NUMPY_NEXTAFTER_HPP
+#define PYTHONIC_NUMPY_NEXTAFTER_HPP
+
+#include "pythonic/include/numpy/nextafter.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME nextafter
+#define NUMPY_NARY_FUNC_SYM std::nextafter
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/nextafter/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/nextafter/accumulate.hpp
new file mode 100644
index 00000000000..af04eb8cb84
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/nextafter/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_NEXTAFTER_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_NEXTAFTER_ACCUMULATE_HPP
+
+#define UFUNC_NAME nextafter
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/not_equal.hpp b/contrib/python/pythran/pythran/pythonic/numpy/not_equal.hpp
new file mode 100644
index 00000000000..27fafd66333
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/not_equal.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_NUMPY_NOTEQUAL_HPP
+#define PYTHONIC_NUMPY_NOTEQUAL_HPP
+
+#include "pythonic/include/numpy/not_equal.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/operator_/ne.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME not_equal
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::ne
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/not_equal/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/not_equal/accumulate.hpp
new file mode 100644
index 00000000000..8f826197ec5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/not_equal/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_NOT_EQUAL_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_NOT_EQUAL_ACCUMULATE_HPP
+
+#define UFUNC_NAME not_equal
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ones_like.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ones_like.hpp
new file mode 100644
index 00000000000..fff0667d25b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ones_like.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_NUMPY_ONESLIKE_HPP
+#define PYTHONIC_NUMPY_ONESLIKE_HPP
+
+#include "pythonic/include/numpy/ones_like.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/numpy/ones.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class E, class dtype>
+ auto ones_like(E const &expr, dtype d)
+ -> decltype(ones(sutils::getshape(expr), d))
+ {
+ return ones(sutils::getshape(expr), d);
+ }
+
+ template <class E>
+ auto ones_like(E const &expr, types::none_type)
+ -> decltype(ones(sutils::getshape(expr),
+ types::dtype_t<typename E::dtype>()))
+ {
+ return ones(sutils::getshape(expr), types::dtype_t<typename E::dtype>());
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/outer.hpp b/contrib/python/pythran/pythran/pythonic/numpy/outer.hpp
new file mode 100644
index 00000000000..53da26e133f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/outer.hpp
@@ -0,0 +1,57 @@
+#ifndef PYTHONIC_NUMPY_OUTER_HPP
+#define PYTHONIC_NUMPY_OUTER_HPP
+
+#include "pythonic/include/numpy/outer.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T0, class pS0, class T1, class pS1>
+ types::ndarray<decltype(std::declval<T0>() + std::declval<T1>()),
+ types::pshape<long, long>>
+ outer(types::ndarray<T0, pS0> const &a, types::ndarray<T1, pS1> const &b)
+ {
+ types::ndarray<decltype(std::declval<T0>() + std::declval<T1>()),
+ types::pshape<long, long>>
+ out(types::pshape<long, long>{a.flat_size(), b.flat_size()},
+ builtins::None);
+ auto iter = out.fbegin();
+ for (auto iter_a = a.fbegin(), end_a = a.fend(); iter_a != end_a;
+ ++iter_a) {
+ auto val_a = *iter_a;
+ iter = std::transform(b.fbegin(), b.fend(), iter,
+ [=](T1 val) { return val_a * val; });
+ }
+ return out;
+ }
+
+ template <class T0, class pS0, class E1>
+ auto outer(types::ndarray<T0, pS0> const &a, E1 const &b)
+ -> decltype(outer(a, asarray(b)))
+ {
+ return outer(a, asarray(b));
+ }
+
+ template <class E0, class T1, class pS1>
+ auto outer(E0 const &a, types::ndarray<T1, pS1> const &b)
+ -> decltype(outer(asarray(a), b))
+ {
+ return outer(asarray(a), b);
+ }
+
+ template <class E0, class E1>
+ auto outer(E0 const &a, E1 const &b)
+ -> decltype(outer(asarray(a), asarray(b)))
+ {
+ return outer(asarray(a), asarray(b));
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/partial_sum.hpp b/contrib/python/pythran/pythran/pythonic/numpy/partial_sum.hpp
new file mode 100644
index 00000000000..baf029c0d18
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/partial_sum.hpp
@@ -0,0 +1,121 @@
+#ifndef PYTHONIC_NUMPY_PARTIAL_SUM_HPP
+#define PYTHONIC_NUMPY_PARTIAL_SUM_HPP
+
+#include "pythonic/include/numpy/partial_sum.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/builtins/ValueError.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ /**
+ * The cast is perform to be numpy compliant
+ *
+ * a = numpy.array([1, 256])
+ * In [10]: numpy.mod.accumulate(a, dtype=numpy.uint32)
+ * Out[10]: array([1, 1], dtype=uint32)
+ * In [11]: numpy.mod.accumulate(a, dtype=numpy.uint8)
+ * Out[11]: array([1, 0], dtype=uint8)
+ */
+ namespace
+ {
+
+ template <class Op, size_t N, class A>
+ struct _partial_sum {
+ template <class E, class F>
+ A operator()(E const &e, F &o)
+ {
+ auto it_begin = e.begin();
+ A acc = _partial_sum<Op, N - 1, A>{}((*it_begin), o);
+ ++it_begin;
+ for (; it_begin < e.end(); ++it_begin)
+ acc = _partial_sum<Op, N - 1, A>{}(*it_begin, o, acc);
+ return acc;
+ }
+ template <class E, class F>
+ A operator()(E const &e, F &o, A acc)
+ {
+ for (auto const &value : e)
+ acc = _partial_sum<Op, N - 1, A>{}(value, o, acc);
+ return acc;
+ }
+ };
+
+ template <class Op, class A>
+ struct _partial_sum<Op, 1, A> {
+ template <class E, class F>
+ A operator()(E const &e, F &o)
+ {
+ auto it_begin = e.begin();
+ A acc = *it_begin;
+ *o = acc;
+ ++it_begin, ++o;
+ for (; it_begin < e.end(); ++it_begin, ++o) {
+ acc = Op{}(acc, (A)*it_begin);
+ *o = acc;
+ }
+ return acc;
+ }
+ template <class E, class F>
+ A operator()(E e, F &o, A acc)
+ {
+ for (auto const &value : e) {
+ acc = Op{}(acc, (A)value);
+ *o = acc;
+ ++o;
+ }
+ return acc;
+ }
+ };
+ }
+
+ template <class Op, class E, class dtype>
+ types::ndarray<typename dtype::type, types::pshape<long>>
+ partial_sum(E const &expr, dtype d)
+ {
+ const long count = expr.flat_size();
+ types::ndarray<typename dtype::type, types::pshape<long>> the_partial_sum{
+ types::make_tuple(count), builtins::None};
+ auto begin_it = the_partial_sum.begin();
+ _partial_sum<Op, E::value, typename dtype::type>{}(expr, begin_it);
+ return the_partial_sum;
+ }
+
+ template <class Op, class E, class dtype>
+ auto partial_sum(E const &expr, long axis, dtype d) ->
+ typename std::enable_if<E::value == 1,
+ decltype(partial_sum<Op, E, dtype>(expr))>::type
+ {
+ if (axis != 0)
+ throw types::ValueError("axis out of bounds");
+ return partial_sum<Op, E, dtype>(expr);
+ }
+
+ template <class Op, class E, class dtype>
+ typename std::enable_if<E::value != 1, partial_sum_type<Op, E, dtype>>::type
+ partial_sum(E const &expr, long axis, dtype d)
+ {
+ if (axis < 0 || size_t(axis) >= E::value)
+ throw types::ValueError("axis out of bounds");
+
+ auto shape = sutils::getshape(expr);
+ partial_sum_type<Op, E, dtype> the_partial_sum{shape, builtins::None};
+ if (axis == 0) {
+ auto it_begin = the_partial_sum.begin();
+ _partial_sum<Op, 1, partial_sum_type2<Op, E, dtype>>{}(expr, it_begin);
+ } else {
+ std::transform(
+ expr.begin(), expr.end(), the_partial_sum.begin(),
+ [axis, d](
+ typename std::iterator_traits<typename E::iterator>::value_type
+ other) { return partial_sum<Op>(other, axis - 1, d); });
+ }
+ return the_partial_sum;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/pi.hpp b/contrib/python/pythran/pythran/pythonic/numpy/pi.hpp
new file mode 100644
index 00000000000..27411db63c1
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/pi.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_NUMPY_PI_HPP
+#define PYTHONIC_NUMPY_PI_HPP
+
+#include "pythonic/include/numpy/pi.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/place.hpp b/contrib/python/pythran/pythran/pythonic/numpy/place.hpp
new file mode 100644
index 00000000000..5e21e7f8af3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/place.hpp
@@ -0,0 +1,51 @@
+#ifndef PYTHONIC_NUMPY_PLACE_HPP
+#define PYTHONIC_NUMPY_PLACE_HPP
+
+#include "pythonic/include/numpy/place.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/numpy/asarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS, class Tp, class pSp, class F>
+ types::none_type place(types::ndarray<T, pS> &expr,
+ types::ndarray<Tp, pSp> const &mask, F const &values)
+ {
+ auto first = expr.fend();
+ auto viter = values.begin(), vend = values.end();
+ auto miter = mask.fbegin();
+ for (auto iter = expr.fbegin(), end = expr.fend(); iter != end;
+ ++iter, ++miter) {
+ if (*miter) {
+ if (first == expr.fend())
+ first = iter;
+ if (viter == vend)
+ viter = values.begin();
+ *iter = *viter;
+ ++viter;
+ }
+ }
+ return builtins::None;
+ }
+
+ template <class T, class pS, class M, class F>
+ types::none_type place(types::ndarray<T, pS> &expr, M const &mask,
+ F const &values)
+ {
+ return place(expr, asarray(mask), values);
+ }
+
+ template <class E, class M, class F>
+ types::none_type place(E &, M const &, F const &)
+ {
+ throw std::runtime_error("place only partially implemented");
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/power/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/power/accumulate.hpp
new file mode 100644
index 00000000000..f79cbad2992
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/power/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_POWER_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_POWER_ACCUMULATE_HPP
+
+#define UFUNC_NAME power
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/product.hpp b/contrib/python/pythran/pythran/pythonic/numpy/product.hpp
new file mode 100644
index 00000000000..a383443c41b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/product.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_PRODUCT_HPP
+#define PYTHONIC_NUMPY_PRODUCT_HPP
+
+#include "pythonic/include/numpy/product.hpp"
+#include "pythonic/numpy/prod.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ptp.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ptp.hpp
new file mode 100644
index 00000000000..572f7b2e236
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ptp.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_NUMPY_PTP_HPP
+#define PYTHONIC_NUMPY_PTP_HPP
+
+#include "pythonic/include/numpy/ptp.hpp"
+
+#include "pythonic/numpy/min.hpp"
+#include "pythonic/numpy/max.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class E>
+ auto ptp(E const &expr, long axis)
+ -> decltype(max(expr, axis) - min(expr, axis))
+ {
+ return max(expr, axis) - min(expr, axis);
+ }
+
+ template <class E>
+ auto ptp(E const &expr) -> decltype(max(expr) - min(expr))
+ {
+ return max(expr) - min(expr);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/put.hpp b/contrib/python/pythran/pythran/pythonic/numpy/put.hpp
new file mode 100644
index 00000000000..627c07992bf
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/put.hpp
@@ -0,0 +1,49 @@
+#ifndef PYTHONIC_NUMPY_PUT_HPP
+#define PYTHONIC_NUMPY_PUT_HPP
+
+#include "pythonic/include/numpy/put.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/numpy/asarray.hpp"
+#include "pythonic/utils/numpy_conversion.hpp"
+#include "pythonic/builtins/ValueError.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class F, class T, class pS, class E>
+ typename std::enable_if<types::is_numexpr_arg<F>::value,
+ types::none_type>::type
+ put(types::ndarray<T, pS> &expr, F const &ind, E const &v)
+ {
+ auto vind = asarray(ind);
+ auto vv = asarray(v);
+ for (long i = 0; i < ind.flat_size(); ++i) {
+ auto val = *(vind.fbegin() + i);
+ if (val >= expr.flat_size() || val < 0)
+ throw types::ValueError("indice out of bound");
+ *(expr.fbegin() + val) = *(vv.fbegin() + i % vv.flat_size());
+ }
+ return builtins::None;
+ }
+
+ template <class T, class pS>
+ types::none_type put(types::ndarray<T, pS> &expr, long ind, T const &v)
+ {
+ if (ind >= expr.flat_size() || ind < 0)
+ throw types::ValueError("indice out of bound");
+ *(expr.fbegin() + ind) = v;
+ return builtins::None;
+ }
+
+ template <class E, class M, class V>
+ types::none_type put(E &, M const &, V const &)
+ {
+ throw std::runtime_error("put only partially implemented");
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/putmask.hpp b/contrib/python/pythran/pythran/pythonic/numpy/putmask.hpp
new file mode 100644
index 00000000000..1640cbed4ad
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/putmask.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_NUMPY_PUTMASK_HPP
+#define PYTHONIC_NUMPY_PUTMASK_HPP
+
+#include "pythonic/include/numpy/putmask.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/numpy/asarray.hpp"
+#include "pythonic/builtins/None.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS, class E, class F>
+ types::none_type putmask(types::ndarray<T, pS> &expr, E const &mask,
+ F const &values)
+ {
+ auto amask = asarray(mask);
+ auto avalues = asarray(values);
+ auto iexpr = expr.fbegin();
+ auto n = avalues.flat_size();
+ for (long i = 0; i < expr.flat_size(); ++i)
+ if (*(amask.fbegin() + i))
+ *(iexpr + i) = *(avalues.fbegin() + i % n);
+ return builtins::None;
+ }
+
+ template <class E, class M, class F>
+ types::none_type putmask(E &, M const &, F const &)
+ {
+ throw std::runtime_error("putmask only partially implemented");
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/rad2deg.hpp b/contrib/python/pythran/pythran/pythonic/numpy/rad2deg.hpp
new file mode 100644
index 00000000000..977848da0c5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/rad2deg.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_NUMPY_RAD2DEG_HPP
+#define PYTHONIC_NUMPY_RAD2DEG_HPP
+
+#include "pythonic/include/numpy/rad2deg.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/numpy/pi.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME rad2deg
+#define NUMPY_NARY_FUNC_SYM wrapper::rad2deg
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/radians.hpp b/contrib/python/pythran/pythran/pythonic/numpy/radians.hpp
new file mode 100644
index 00000000000..f86140729be
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/radians.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_RADIANS_HPP
+#define PYTHONIC_NUMPY_RADIANS_HPP
+
+#include "pythonic/include/numpy/radians.hpp"
+#include "pythonic/numpy/deg2rad.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/binomial.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/binomial.hpp
new file mode 100644
index 00000000000..5d9dbda7ca3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/binomial.hpp
@@ -0,0 +1,55 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_BINOMIAL_HPP
+#define PYTHONIC_NUMPY_RANDOM_BINOMIAL_HPP
+
+#include "pythonic/include/numpy/random/binomial.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_expr.hpp"
+
+#include "pythonic/types/exceptions.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ namespace details
+ {
+ inline void parameters_check(double n, double p)
+ {
+ if (n < 0)
+ throw pythonic::types::ValueError("n < 0");
+ if (p < 0)
+ throw pythonic::types::ValueError("p < 0");
+ else if (p > 1)
+ throw pythonic::types::ValueError("p > 1");
+ }
+ } // namespace details
+
+ template <class pS>
+ types::ndarray<long, pS> binomial(double n, double p, pS const &shape)
+ {
+ details::parameters_check(n, p);
+ types::ndarray<long, pS> result{shape, types::none_type()};
+ std::binomial_distribution<long> distribution{(long)n, p};
+ std::generate(result.fbegin(), result.fend(),
+ [&]() { return distribution(details::generator); });
+ return result;
+ }
+
+ inline auto binomial(double n, double p, long size)
+ -> decltype(binomial(n, p, types::array<long, 1>{{size}}))
+ {
+ return binomial(n, p, types::array<long, 1>{{size}});
+ }
+
+ inline long binomial(double n, double p, types::none_type d)
+ {
+ details::parameters_check(n, p);
+ return std::binomial_distribution<long>{(long)n, p}(details::generator);
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/bytes.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/bytes.hpp
new file mode 100644
index 00000000000..a4c870b98ca
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/bytes.hpp
@@ -0,0 +1,33 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_BYTES_HPP
+#define PYTHONIC_NUMPY_RANDOM_BYTES_HPP
+
+#include "pythonic/include/numpy/random/bytes.hpp"
+#include "pythonic/include/numpy/random/generator.hpp"
+
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <random>
+#include <string>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ inline types::str bytes(long length)
+ {
+ // dummy init + rewrite is faster than reserve && push_back
+ types::str result(std::string(length, 0));
+ std::uniform_int_distribution<long> distribution{0, 255};
+ std::generate(result.chars().begin(), result.chars().end(), [&]() {
+ return static_cast<char>(distribution(details::generator));
+ });
+ return result;
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/chisquare.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/chisquare.hpp
new file mode 100644
index 00000000000..d66fd816abf
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/chisquare.hpp
@@ -0,0 +1,46 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_CHISQUARE_HPP
+#define PYTHONIC_NUMPY_RANDOM_CHISQUARE_HPP
+
+#include "pythonic/include/numpy/random/chisquare.hpp"
+#include "pythonic/include/numpy/random/generator.hpp"
+
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ types::ndarray<double, pS> chisquare(double df, pS const &shape)
+ {
+ types::ndarray<double, pS> result{shape, types::none_type()};
+ std::chi_squared_distribution<double> distribution{df};
+ std::generate(result.fbegin(), result.fend(),
+ [&]() { return distribution(details::generator); });
+ return result;
+ }
+
+ inline auto chisquare(double df, long size)
+ -> decltype(chisquare(df, types::array<long, 1>{{size}}))
+ {
+
+ return chisquare(df, types::array<long, 1>{{size}});
+ }
+
+ inline double chisquare(double df, types::none_type d)
+ {
+ return std::chi_squared_distribution<double>{df}(details::generator);
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/choice.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/choice.hpp
new file mode 100644
index 00000000000..680789cde0d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/choice.hpp
@@ -0,0 +1,123 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_CHOICE_HPP
+#define PYTHONIC_NUMPY_RANDOM_CHOICE_HPP
+
+#include "pythonic/include/numpy/random/choice.hpp"
+#include "pythonic/include/numpy/random/generator.hpp"
+
+#include "pythonic/builtins/NotImplementedError.hpp"
+#include "pythonic/numpy/random/randint.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ /***********************************************************
+ * Implementation with long as first argument
+ **********************************************************/
+ template <class pS, class P>
+ types::ndarray<long, pS> choice(long max, pS const &shape, bool replace,
+ P const &p)
+ {
+ if (!replace)
+ throw pythonic::builtins::NotImplementedError(
+ "Choice without replacement is ! implemented, ask if you want "
+ "it");
+
+ types::ndarray<long, pS> result{shape, types::none_type()};
+ std::discrete_distribution<long> distribution{p.begin(), p.end()};
+ std::generate(result.fbegin(), result.fend(),
+ [&]() { return distribution(details::generator); });
+ return result;
+ }
+
+ template <class P>
+ types::ndarray<long, types::pshape<long>> choice(long max, long size,
+ bool replace, P &&p)
+ {
+ return choice(max, types::pshape<long>{size}, replace,
+ std::forward<P>(p));
+ }
+
+ template <class T>
+ auto choice(long max, T &&size)
+ -> decltype(randint(0, max, std::forward<T>(size)))
+ {
+ return randint(0, max, std::forward<T>(size));
+ }
+
+ inline long choice(long max)
+ {
+ return randint(max);
+ }
+
+ /***********************************************************
+ * Implementation with array as first argument
+ **********************************************************/
+
+ template <class T>
+ typename T::dtype choice(T const &a)
+ {
+ // This is a numpy constraint
+ static_assert(T::value == 1, "ValueError: a must be 1-dimensional");
+
+ return a.fast(randint(a.size()));
+ }
+
+ template <class T, class pS>
+ types::ndarray<typename T::dtype, pS> choice(T const &a, pS const &shape)
+ {
+ // This is a numpy constraint
+ static_assert(T::value == 1, "ValueError: a must be 1-dimensional");
+
+ types::ndarray<typename T::dtype, pS> result{shape, types::none_type()};
+ std::uniform_int_distribution<long> distribution{0, a.size() - 1};
+ std::generate(result.fbegin(), result.fend(),
+ [&]() { return a[distribution(details::generator)]; });
+ return result;
+ }
+
+ template <class T>
+ types::ndarray<typename T::dtype, types::pshape<long>> choice(T &&a,
+ long size)
+ {
+ return choice(std::forward<T>(a), types::pshape<long>{size});
+ }
+
+ template <class T, class pS, class P>
+ types::ndarray<typename T::dtype, pS> choice(T const &a, pS const &shape,
+ bool replace, P const &p)
+ {
+ // This is a numpy constraint
+ static_assert(T::value == 1, "ValueError: a must be 1-dimensional");
+
+ if (!replace)
+ throw pythonic::builtins::NotImplementedError(
+ "Choice without replacement is ! implemented, ask if you want "
+ "it");
+
+ types::ndarray<typename T::dtype, pS> result{shape, types::none_type()};
+ std::discrete_distribution<long> distribution{p.begin(), p.end()};
+ std::generate(result.fbegin(), result.fend(),
+ [&]() { return a[distribution(details::generator)]; });
+ return result;
+ }
+
+ template <class T, class P>
+ types::ndarray<typename T::dtype, types::pshape<long>>
+ choice(T &&a, long size, bool replace, P &&p)
+ {
+ return choice(std::forward<T>(a), types::pshape<long>{size}, replace,
+ std::forward<P>(p));
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/dirichlet.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/dirichlet.hpp
new file mode 100644
index 00000000000..0eea6cf8279
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/dirichlet.hpp
@@ -0,0 +1,46 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_DIRICHLET_HPP
+#define PYTHONIC_NUMPY_RANDOM_DIRICHLET_HPP
+
+#include "pythonic/include/numpy/random/dirichlet.hpp"
+#include "pythonic/include/numpy/random/generator.hpp"
+
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ types::ndarray<double, pS> dirichlet(double alpha, pS const &shape)
+ {
+ types::ndarray<double, pS> result{shape, types::none_type()};
+ std::dirichlet_distribution<double> distribution{alpha};
+ std::generate(result.fbegin(), result.fend(),
+ [&]() { return distribution(details::generator); });
+ return result;
+ }
+
+ inline auto dirichlet(double alpha, long size)
+ -> decltype(dirichlet(alpha, types::array<long, 1>{{size}}))
+ {
+
+ return dirichlet(alpha, types::array<long, 1>{{size}});
+ }
+
+ inline double dirichlet(double alpha, types::none_type d)
+ {
+ return std::dirichlet_distribution<double>{alpha}(details::generator);
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/exponential.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/exponential.hpp
new file mode 100644
index 00000000000..37d2d019d13
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/exponential.hpp
@@ -0,0 +1,47 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_EXPONENTIAL_HPP
+#define PYTHONIC_NUMPY_RANDOM_EXPONENTIAL_HPP
+
+#include "pythonic/include/numpy/random/exponential.hpp"
+#include "pythonic/include/numpy/random/generator.hpp"
+
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ types::ndarray<double, pS> exponential(double scale, pS const &shape)
+ {
+ types::ndarray<double, pS> result{shape, types::none_type()};
+ std::exponential_distribution<double> distribution{1 / scale};
+ std::generate(result.fbegin(), result.fend(),
+ [&]() { return distribution(details::generator); });
+ return result;
+ }
+
+ inline auto exponential(double scale, long size)
+ -> decltype(exponential(scale, types::array<long, 1>{{size}}))
+ {
+
+ return exponential(scale, types::array<long, 1>{{size}});
+ }
+
+ inline double exponential(double scale, types::none_type d)
+ {
+ return std::exponential_distribution<double>{1 /
+ scale}(details::generator);
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/f.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/f.hpp
new file mode 100644
index 00000000000..fbc43228563
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/f.hpp
@@ -0,0 +1,51 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_F_HPP
+#define PYTHONIC_NUMPY_RANDOM_F_HPP
+
+#include "pythonic/include/numpy/random/f.hpp"
+#include "pythonic/include/numpy/random/generator.hpp"
+
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ types::ndarray<double, pS> f(double dfnum, double dfden, pS const &shape)
+ {
+ types::ndarray<double, pS> result{shape, types::none_type()};
+ std::chi_squared_distribution<double> distribution{dfnum};
+ std::chi_squared_distribution<double> distribution2{dfden};
+ std::generate(result.fbegin(), result.fend(), [&]() {
+ return (distribution(details::generator) * dfden) /
+ (distribution2(details::generator) * dfnum);
+ });
+ return result;
+ }
+
+ inline auto f(double dfnum, double dfden, long size)
+ -> decltype(f(dfnum, dfden, types::array<long, 1>{{size}}))
+ {
+ return f(dfnum, dfden, types::array<long, 1>{{size}});
+ }
+
+ inline double f(double dfnum, double dfden, types::none_type d)
+ {
+ return (std::chi_squared_distribution<double>{dfnum}(
+ details::generator)*dfden) /
+ (std::chi_squared_distribution<double>{dfden}(
+ details::generator)*dfnum);
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/gamma.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/gamma.hpp
new file mode 100644
index 00000000000..55bbe5a7a2b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/gamma.hpp
@@ -0,0 +1,46 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_GAMMA_HPP
+#define PYTHONIC_NUMPY_RANDOM_GAMMA_HPP
+
+#include "pythonic/include/numpy/random/gamma.hpp"
+#include "pythonic/include/numpy/random/generator.hpp"
+
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ types::ndarray<double, pS> gamma(double shape, double scale,
+ pS const &array_shape)
+ {
+ types::ndarray<double, pS> result{array_shape, types::none_type()};
+ std::gamma_distribution<double> distribution{shape, scale};
+ std::generate(result.fbegin(), result.fend(),
+ [&]() { return distribution(details::generator); });
+ return result;
+ }
+
+ inline auto gamma(double shape, double scale, long size)
+ -> decltype(gamma(shape, scale, types::array<long, 1>{{size}}))
+ {
+ return gamma(shape, scale, types::array<long, 1>{{size}});
+ }
+
+ inline double gamma(double shape, double scale, types::none_type d)
+ {
+ return std::gamma_distribution<double>{shape, scale}(details::generator);
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/geometric.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/geometric.hpp
new file mode 100644
index 00000000000..b1f661f86e3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/geometric.hpp
@@ -0,0 +1,45 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_GEOMETRIC_HPP
+#define PYTHONIC_NUMPY_RANDOM_GEOMETRIC_HPP
+
+#include "pythonic/include/numpy/random/generator.hpp"
+#include "pythonic/include/numpy/random/geometric.hpp"
+
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ types::ndarray<double, pS> geometric(double p, pS const &shape)
+ {
+ types::ndarray<double, pS> result{shape, types::none_type()};
+ std::geometric_distribution<int> distribution{p};
+ std::generate(result.fbegin(), result.fend(),
+ [&]() { return distribution(details::generator); });
+ return result;
+ }
+
+ inline auto geometric(double p, long size)
+ -> decltype(geometric(p, types::array<long, 1>{{size}}))
+ {
+ return geometric(p, types::array<long, 1>{{size}});
+ }
+
+ inline double geometric(double p, types::none_type d)
+ {
+ return std::geometric_distribution<int>{p}(details::generator);
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/gumbel.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/gumbel.hpp
new file mode 100644
index 00000000000..d74adeb3496
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/gumbel.hpp
@@ -0,0 +1,49 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_GUMBEL_HPP
+#define PYTHONIC_NUMPY_RANDOM_GUMBEL_HPP
+
+#include "pythonic/include/numpy/random/generator.hpp"
+#include "pythonic/include/numpy/random/gumbel.hpp"
+
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ types::ndarray<double, pS> gumbel(double loc, double scale, pS const &shape)
+ {
+ types::ndarray<double, pS> result{shape, types::none_type()};
+ std::generate(result.fbegin(), result.fend(),
+ [&]() { return gumbel(loc, scale); });
+ return result;
+ }
+
+ inline auto gumbel(double loc, double scale, long size)
+ -> decltype(gumbel(loc, scale, types::array<long, 1>{{size}}))
+ {
+ return gumbel(loc, scale, types::array<long, 1>{{size}});
+ }
+
+ inline double gumbel(double loc, double scale, types::none_type d)
+ {
+ double U =
+ std::uniform_real_distribution<double>{0., 1.}(details::generator);
+ if (U < 1.0) {
+ return loc - scale * xsimd::log(-xsimd::log(U));
+ }
+ return gumbel(loc, scale);
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/laplace.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/laplace.hpp
new file mode 100644
index 00000000000..ce2eac46f0a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/laplace.hpp
@@ -0,0 +1,54 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_LAPLACE_HPP
+#define PYTHONIC_NUMPY_RANDOM_LAPLACE_HPP
+
+#include "pythonic/include/numpy/random/generator.hpp"
+#include "pythonic/include/numpy/random/laplace.hpp"
+
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ types::ndarray<double, pS> laplace(double loc, double scale,
+ pS const &shape)
+ {
+ types::ndarray<double, pS> result{shape, types::none_type()};
+ std::generate(result.fbegin(), result.fend(),
+ [&]() { return laplace(loc, scale); });
+ return result;
+ }
+
+ inline auto laplace(double loc, double scale, long size)
+ -> decltype(laplace(loc, scale, types::array<long, 1>{{size}}))
+ {
+ return laplace(loc, scale, types::array<long, 1>{{size}});
+ }
+
+ inline double laplace(double loc, double scale, types::none_type d)
+ {
+ double U =
+ std::uniform_real_distribution<double>{0., 1.}(details::generator);
+ if (U >= 0.5) {
+ U = loc - scale * xsimd::log(2.0 - U - U);
+ } else if (U > 0.0) {
+ U = loc + scale * xsimd::log(U + U);
+ } else {
+ U = laplace(loc, scale);
+ }
+ return U;
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/logistic.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/logistic.hpp
new file mode 100644
index 00000000000..6537964c3f5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/logistic.hpp
@@ -0,0 +1,50 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_LOGISTIC_HPP
+#define PYTHONIC_NUMPY_RANDOM_LOGISTIC_HPP
+
+#include "pythonic/include/numpy/random/generator.hpp"
+#include "pythonic/include/numpy/random/logistic.hpp"
+
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ types::ndarray<double, pS> logistic(double loc, double scale,
+ pS const &shape)
+ {
+ types::ndarray<double, pS> result{shape, types::none_type()};
+ std::generate(result.fbegin(), result.fend(),
+ [&]() { return logistic(loc, scale); });
+ return result;
+ }
+
+ inline auto logistic(double loc, double scale, long size)
+ -> decltype(logistic(loc, scale, types::array<long, 1>{{size}}))
+ {
+ return logistic(loc, scale, types::array<long, 1>{{size}});
+ }
+
+ inline double logistic(double loc, double scale, types::none_type d)
+ {
+ double U =
+ std::uniform_real_distribution<double>{0., 1.}(details::generator);
+ if (U > 0.0) {
+ return loc + scale * xsimd::log(U / (1 - U));
+ }
+ return logistic(loc, scale);
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/lognormal.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/lognormal.hpp
new file mode 100644
index 00000000000..91d2843b1d7
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/lognormal.hpp
@@ -0,0 +1,47 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_LOGNORMAL_HPP
+#define PYTHONIC_NUMPY_RANDOM_LOGNORMAL_HPP
+
+#include "pythonic/include/numpy/random/generator.hpp"
+#include "pythonic/include/numpy/random/lognormal.hpp"
+
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ types::ndarray<double, pS> lognormal(double mean, double sigma,
+ pS const &shape)
+ {
+ types::ndarray<double, pS> result{shape, types::none_type()};
+ std::lognormal_distribution<double> distribution{mean, sigma};
+ std::generate(result.fbegin(), result.fend(),
+ [&]() { return distribution(details::generator); });
+ return result;
+ }
+
+ inline auto lognormal(double mean, double sigma, long size)
+ -> decltype(lognormal(mean, sigma, types::array<long, 1>{{size}}))
+ {
+ return lognormal(mean, sigma, types::array<long, 1>{{size}});
+ }
+
+ inline double lognormal(double mean, double sigma, types::none_type d)
+ {
+ return std::lognormal_distribution<double>{mean,
+ sigma}(details::generator);
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/logseries.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/logseries.hpp
new file mode 100644
index 00000000000..c99fb95a63a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/logseries.hpp
@@ -0,0 +1,69 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_LOGSERIES_HPP
+#define PYTHONIC_NUMPY_RANDOM_LOGSERIES_HPP
+
+#include "pythonic/include/numpy/random/generator.hpp"
+#include "pythonic/include/numpy/random/logseries.hpp"
+
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+#include <math.h>
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ types::ndarray<double, pS> logseries(double p, pS const &shape)
+ {
+ types::ndarray<double, pS> result{shape, types::none_type()};
+ std::generate(result.fbegin(), result.fend(),
+ [&]() { return logseries(p); });
+ return result;
+ }
+
+ inline auto logseries(double p, long size)
+ -> decltype(logseries(p, types::array<long, 1>{{size}}))
+ {
+ return logseries(p, types::array<long, 1>{{size}});
+ }
+
+ inline double logseries(double p, types::none_type d)
+ {
+ double q, r, U, V;
+ double result;
+
+ r = log1p(-p);
+
+ while (1) {
+ V = std::uniform_real_distribution<double>{0., 1.}(details::generator);
+ if (V >= p) {
+ return 1;
+ }
+ U = std::uniform_real_distribution<double>{0., 1.}(details::generator);
+ q = -expm1(r * U);
+ if (V <= q * q) {
+ result = (double)floor(1 + log(V) / log(q));
+ if ((result < 1) || (V == 0.0)) {
+ continue;
+ } else {
+ return result;
+ }
+ }
+ if (V >= q) {
+ return 1;
+ }
+ return 2;
+ }
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/negative_binomial.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/negative_binomial.hpp
new file mode 100644
index 00000000000..3f015f3f5d3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/negative_binomial.hpp
@@ -0,0 +1,47 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_NEGATIVE_BINOMIAL_HPP
+#define PYTHONIC_NUMPY_RANDOM_NEGATIVE_BINOMIAL_HPP
+
+#include "pythonic/include/numpy/random/generator.hpp"
+#include "pythonic/include/numpy/random/negative_binomial.hpp"
+
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ types::ndarray<long, pS> negative_binomial(long n, double p,
+ pS const &shape)
+ {
+ types::ndarray<long, pS> result{shape, types::none_type()};
+ std::negative_binomial_distribution<long> distribution{n, p};
+ std::generate(result.fbegin(), result.fend(),
+ [&]() { return distribution(details::generator); });
+ return result;
+ }
+
+ inline auto negative_binomial(long n, double p, long size)
+ -> decltype(negative_binomial(n, p, types::array<long, 1>{{size}}))
+ {
+ return negative_binomial(n, p, types::array<long, 1>{{size}});
+ }
+
+ inline long negative_binomial(long n, double p, types::none_type d)
+ {
+ std::negative_binomial_distribution<long> distribution{n, p};
+ return distribution(details::generator);
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/normal.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/normal.hpp
new file mode 100644
index 00000000000..3c755d14325
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/normal.hpp
@@ -0,0 +1,45 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_NORMAL_HPP
+#define PYTHONIC_NUMPY_RANDOM_NORMAL_HPP
+
+#include "pythonic/include/numpy/random/generator.hpp"
+#include "pythonic/include/numpy/random/normal.hpp"
+
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ types::ndarray<double, pS> normal(double loc, double scale, pS const &shape)
+ {
+ types::ndarray<double, pS> result{shape, types::none_type()};
+ std::normal_distribution<double> distribution{loc, scale};
+ std::generate(result.fbegin(), result.fend(),
+ [&]() { return distribution(details::generator); });
+ return result;
+ }
+
+ inline auto normal(double loc, double scale, long size)
+ -> decltype(normal(loc, scale, types::array<long, 1>{{size}}))
+ {
+ return normal(loc, scale, types::array<long, 1>{{size}});
+ }
+
+ inline double normal(double loc, double scale, types::none_type d)
+ {
+ return std::normal_distribution<double>{loc, scale}(details::generator);
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/pareto.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/pareto.hpp
new file mode 100644
index 00000000000..3cd7349d375
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/pareto.hpp
@@ -0,0 +1,48 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_PARETO_HPP
+#define PYTHONIC_NUMPY_RANDOM_PARETO_HPP
+
+#include "pythonic/include/numpy/random/generator.hpp"
+#include "pythonic/include/numpy/random/pareto.hpp"
+
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ types::ndarray<double, pS> pareto(double a, pS const &shape)
+ {
+ types::ndarray<double, pS> result{shape, types::none_type()};
+ std::exponential_distribution<double> distribution{};
+ std::generate(result.fbegin(), result.fend(), [&]() {
+ return expm1(distribution(details::generator) / a);
+ });
+ return result;
+ }
+
+ inline auto pareto(double a, long size)
+ -> decltype(pareto(a, types::array<long, 1>{{size}}))
+ {
+
+ return pareto(a, types::array<long, 1>{{size}});
+ }
+
+ inline double pareto(double a, types::none_type d)
+ {
+ return expm1(std::exponential_distribution<double>{}(details::generator) /
+ a);
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/poisson.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/poisson.hpp
new file mode 100644
index 00000000000..27249929bda
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/poisson.hpp
@@ -0,0 +1,45 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_POISSON_HPP
+#define PYTHONIC_NUMPY_RANDOM_POISSON_HPP
+
+#include "pythonic/include/numpy/random/generator.hpp"
+#include "pythonic/include/numpy/random/poisson.hpp"
+
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ types::ndarray<double, pS> poisson(double lam, pS const &shape)
+ {
+ types::ndarray<double, pS> result{shape, types::none_type()};
+ std::poisson_distribution<long> distribution{lam};
+ std::generate(result.fbegin(), result.fend(),
+ [&]() { return distribution(details::generator); });
+ return result;
+ }
+
+ inline auto poisson(double lam, long size)
+ -> decltype(poisson(lam, types::array<long, 1>{{size}}))
+ {
+ return poisson(lam, types::array<long, 1>{{size}});
+ }
+
+ inline double poisson(double lam, types::none_type d)
+ {
+ return std::poisson_distribution<long>{lam}(details::generator);
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/power.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/power.hpp
new file mode 100644
index 00000000000..8178ff4f96c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/power.hpp
@@ -0,0 +1,47 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_POWER_HPP
+#define PYTHONIC_NUMPY_RANDOM_POWER_HPP
+
+#include "pythonic/include/numpy/random/generator.hpp"
+#include "pythonic/include/numpy/random/power.hpp"
+
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+#include <math.h>
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ types::ndarray<double, pS> power(double a, pS const &shape)
+ {
+ types::ndarray<double, pS> result{shape, types::none_type()};
+ std::generate(result.fbegin(), result.fend(), [&]() { return power(a); });
+
+ return result;
+ }
+
+ inline auto power(double a, long size)
+ -> decltype(power(a, types::array<long, 1>{{size}}))
+ {
+ return power(a, types::array<long, 1>{{size}});
+ }
+
+ inline double power(double a, types::none_type d)
+ {
+ return pow(
+ -expm1(-std::exponential_distribution<double>{}(details::generator)),
+ 1. / a);
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/rand.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/rand.hpp
new file mode 100644
index 00000000000..234e32f31a2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/rand.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_RAND_HPP
+#define PYTHONIC_NUMPY_RANDOM_RAND_HPP
+
+#include "pythonic/include/numpy/random/rand.hpp"
+
+#include "pythonic/numpy/random/random.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class... T>
+ types::ndarray<double, types::array<long, sizeof...(T)>> rand(T... shape)
+ {
+ return random(types::array<long, sizeof...(T)>{{shape...}});
+ }
+
+ inline double rand()
+ {
+ return random();
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/randint.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/randint.hpp
new file mode 100644
index 00000000000..bed34f861c5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/randint.hpp
@@ -0,0 +1,67 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_RANDINT_HPP
+#define PYTHONIC_NUMPY_RANDOM_RANDINT_HPP
+
+#include "pythonic/include/numpy/random/generator.hpp"
+#include "pythonic/include/numpy/random/randint.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ typename std::enable_if<!std::is_integral<pS>::value,
+ types::ndarray<long, pS>>::type
+ randint(long min, long max, pS const &shape)
+ {
+ types::ndarray<long, pS> result{shape, types::none_type()};
+ std::uniform_int_distribution<long> distribution{min, max - 1};
+ std::generate(result.fbegin(), result.fend(),
+ [&]() { return distribution(details::generator); });
+ return result;
+ }
+
+ template <class pS>
+ typename std::enable_if<std::is_integral<pS>::value,
+ types::ndarray<long, types::pshape<long>>>::type
+ randint(long min, long max, pS const &shape)
+ {
+ return randint(min, max, types::pshape<long>{shape});
+ }
+
+ template <class pS>
+ auto randint(long max, types::none_type, pS const &shape)
+ -> decltype(randint(0, max, shape))
+ {
+ return randint(0, max, shape);
+ }
+
+ inline auto randint(long min, long max, long size)
+ -> decltype(randint(min, max, types::array<long, 1>{{size}}))
+ {
+ return randint(min, max, types::array<long, 1>{{size}});
+ }
+
+ inline long randint(long max, types::none_type)
+ {
+ return std::uniform_int_distribution<long>{0,
+ max - 1}(details::generator);
+ }
+
+ inline long randint(long min, long max)
+ {
+ return std::uniform_int_distribution<long>{min,
+ max - 1}(details::generator);
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/randn.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/randn.hpp
new file mode 100644
index 00000000000..75198a9c514
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/randn.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_RANDN_HPP
+#define PYTHONIC_NUMPY_RANDOM_RANDN_HPP
+
+#include "pythonic/include/numpy/random/randn.hpp"
+
+#include "pythonic/numpy/random/standard_normal.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class... T>
+ types::ndarray<double, types::array<long, sizeof...(T)>> randn(T... shape)
+ {
+ return standard_normal(types::array<long, sizeof...(T)>{{shape...}});
+ }
+
+ inline double randn()
+ {
+ return standard_normal();
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/random.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/random.hpp
new file mode 100644
index 00000000000..6c131c10f7a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/random.hpp
@@ -0,0 +1,45 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_RANDOM_HPP
+#define PYTHONIC_NUMPY_RANDOM_RANDOM_HPP
+
+#include "pythonic/include/numpy/random/generator.hpp"
+#include "pythonic/include/numpy/random/random.hpp"
+
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ types::ndarray<double, pS> random(pS const &shape)
+ {
+ types::ndarray<double, pS> result{shape, types::none_type()};
+ std::uniform_real_distribution<double> distribution{0., 1.};
+ std::generate(result.fbegin(), result.fend(),
+ [&]() { return distribution(details::generator); });
+ return result;
+ }
+
+ inline auto random(long size)
+ -> decltype(random(types::array<long, 1>{{size}}))
+ {
+ return random(types::array<long, 1>{{size}});
+ }
+
+ inline double random(types::none_type d)
+ {
+ return std::uniform_real_distribution<double>{0., 1.}(details::generator);
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/random_integers.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/random_integers.hpp
new file mode 100644
index 00000000000..c71da490382
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/random_integers.hpp
@@ -0,0 +1,34 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_RANDOM_INTEGERS_HPP
+#define PYTHONIC_NUMPY_RANDOM_RANDOM_INTEGERS_HPP
+
+#include "pythonic/include/numpy/random/random_integers.hpp"
+
+#include "pythonic/numpy/random/randint.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+ template <class T>
+ auto random_integers(long min, long max, T &&size)
+ -> decltype(randint(min, max, std::forward<T>(size)))
+ {
+ return randint(min, max + 1, std::forward<T>(size));
+ }
+
+ inline long random_integers(long max)
+ {
+ return randint(1, max + 1);
+ }
+
+ inline long random_integers(long min, long max)
+ {
+ return randint(min, max + 1);
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/random_sample.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/random_sample.hpp
new file mode 100644
index 00000000000..15aa5cf01fa
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/random_sample.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_RANDOM_SAMPLE_HPP
+#define PYTHONIC_NUMPY_RANDOM_RANDOM_SAMPLE_HPP
+
+#include "pythonic/include/numpy/random/random_sample.hpp"
+#include "pythonic/numpy/random/random.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/ranf.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/ranf.hpp
new file mode 100644
index 00000000000..93b099b4f5b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/ranf.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_RANF_HPP
+#define PYTHONIC_NUMPY_RANDOM_RANF_HPP
+
+#include "pythonic/include/numpy/random/ranf.hpp"
+#include "pythonic/numpy/random/random.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/rayleigh.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/rayleigh.hpp
new file mode 100644
index 00000000000..c8f5d44a896
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/rayleigh.hpp
@@ -0,0 +1,47 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_RAYLEIGH_HPP
+#define PYTHONIC_NUMPY_RANDOM_RAYLEIGH_HPP
+
+#include "pythonic/include/numpy/random/generator.hpp"
+#include "pythonic/include/numpy/random/rayleigh.hpp"
+
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+#include <math.h>
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ types::ndarray<double, pS> rayleigh(double scale, pS const &array_shape)
+ {
+ types::ndarray<double, pS> result{array_shape, types::none_type()};
+ std::generate(result.fbegin(), result.fend(),
+ [&]() { return rayleigh(scale); });
+ return result;
+ }
+
+ inline auto rayleigh(double scale, long size)
+ -> decltype(rayleigh(scale, types::array<long, 1>{{size}}))
+ {
+ return rayleigh(scale, types::array<long, 1>{{size}});
+ }
+
+ inline double rayleigh(double scale, types::none_type d)
+ {
+ return scale *
+ sqrt(-2.0 * log(1.0 - std::uniform_real_distribution<double>{
+ 0., 1.}(details::generator)));
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/sample.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/sample.hpp
new file mode 100644
index 00000000000..06ffab8818e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/sample.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_SAMPLE_HPP
+#define PYTHONIC_NUMPY_RANDOM_SAMPLE_HPP
+
+#include "pythonic/include/numpy/random/sample.hpp"
+#include "pythonic/numpy/random/random.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/seed.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/seed.hpp
new file mode 100644
index 00000000000..a00d441b25a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/seed.hpp
@@ -0,0 +1,30 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_SEED_HPP
+#define PYTHONIC_NUMPY_RANDOM_SEED_HPP
+
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/include/numpy/random/seed.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace random
+ {
+
+ inline types::none_type seed(long s)
+ {
+ details::generator.seed(s);
+ return builtins::None;
+ }
+
+ inline types::none_type seed(types::none_type)
+ {
+ details::generator.seed();
+ return builtins::None;
+ }
+ } // namespace random
+} // namespace numpy
+
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/shuffle.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/shuffle.hpp
new file mode 100644
index 00000000000..13e1451b82f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/shuffle.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_SHUFFLE_HPP
+#define PYTHONIC_NUMPY_RANDOM_SHUFFLE_HPP
+
+#include "pythonic/include/numpy/random/shuffle.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/builtins/None.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace random
+ {
+ template <class T>
+ types::none_type shuffle(T &seq)
+ {
+ std::shuffle(seq.begin(), seq.end(), details::generator);
+ return builtins::None;
+ }
+ }
+}
+
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/standard_exponential.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/standard_exponential.hpp
new file mode 100644
index 00000000000..f7c57b4dca6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/standard_exponential.hpp
@@ -0,0 +1,42 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_STANDARD_EXPONENTIAL_HPP
+#define PYTHONIC_NUMPY_RANDOM_STANDARD_EXPONENTIAL_HPP
+
+#include "pythonic/include/numpy/random/generator.hpp"
+#include "pythonic/include/numpy/random/standard_exponential.hpp"
+
+#include "pythonic/numpy/random/exponential.hpp"
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ types::ndarray<double, pS> standard_exponential(pS const &shape)
+ {
+ return exponential(1., shape);
+ }
+
+ inline auto standard_exponential(long size)
+ -> decltype(standard_exponential(types::array<long, 1>{{size}}))
+ {
+ return standard_exponential(types::array<long, 1>{{size}});
+ }
+
+ inline double standard_exponential(types::none_type d)
+ {
+ return exponential(1., d);
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/standard_gamma.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/standard_gamma.hpp
new file mode 100644
index 00000000000..8deed136a99
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/standard_gamma.hpp
@@ -0,0 +1,42 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_STANDARD_GAMMA_HPP
+#define PYTHONIC_NUMPY_RANDOM_STANDARD_GAMMA_HPP
+
+#include "pythonic/include/numpy/random/generator.hpp"
+#include "pythonic/include/numpy/random/standard_gamma.hpp"
+
+#include "pythonic/numpy/random/gamma.hpp"
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ types::ndarray<double, pS> standard_gamma(double s, pS const &shape)
+ {
+ return gamma(s, 1., shape);
+ }
+
+ inline auto standard_gamma(double s, long size)
+ -> decltype(standard_gamma(s, types::array<long, 1>{{size}}))
+ {
+ return standard_gamma(s, types::array<long, 1>{{size}});
+ }
+
+ inline double standard_gamma(double s, types::none_type d)
+ {
+ return gamma(s, 1., d);
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/standard_normal.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/standard_normal.hpp
new file mode 100644
index 00000000000..fb7b40712e4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/standard_normal.hpp
@@ -0,0 +1,42 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_STANDARD_NORMAL_HPP
+#define PYTHONIC_NUMPY_RANDOM_STANDARD_NORMAL_HPP
+
+#include "pythonic/include/numpy/random/generator.hpp"
+#include "pythonic/include/numpy/random/standard_normal.hpp"
+
+#include "pythonic/numpy/random/normal.hpp"
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ types::ndarray<double, pS> standard_normal(pS const &shape)
+ {
+ return normal(0., 1., shape);
+ }
+
+ inline auto standard_normal(long size)
+ -> decltype(standard_normal(types::array<long, 1>{{size}}))
+ {
+ return standard_normal(types::array<long, 1>{{size}});
+ }
+
+ inline double standard_normal(types::none_type d)
+ {
+ return normal(0., 1., d);
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/uniform.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/uniform.hpp
new file mode 100644
index 00000000000..cedfd74eca3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/uniform.hpp
@@ -0,0 +1,47 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_RAYLEIGH_HPP
+#define PYTHONIC_NUMPY_RANDOM_RAYLEIGH_HPP
+
+#include "pythonic/include/numpy/random/generator.hpp"
+#include "pythonic/include/numpy/random/uniform.hpp"
+
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+#include <math.h>
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ types::ndarray<double, pS> uniform(double low, double high,
+ pS const &array_shape)
+ {
+ types::ndarray<double, pS> result{array_shape, types::none_type()};
+ std::generate(result.fbegin(), result.fend(),
+ [&]() { return uniform(low, high); });
+ return result;
+ }
+
+ inline auto uniform(double low, double high, long size)
+ -> decltype(uniform(low, high, types::array<long, 1>{{size}}))
+ {
+ return uniform(low, high, types::array<long, 1>{{size}});
+ }
+
+ inline double uniform(double low, double high, types::none_type d)
+ {
+ return std::uniform_real_distribution<double>{low,
+ high}(details::generator);
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/random/weibull.hpp b/contrib/python/pythran/pythran/pythonic/numpy/random/weibull.hpp
new file mode 100644
index 00000000000..ee5b6030321
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/random/weibull.hpp
@@ -0,0 +1,46 @@
+#ifndef PYTHONIC_NUMPY_RANDOM_WEIBULL_HPP
+#define PYTHONIC_NUMPY_RANDOM_WEIBULL_HPP
+
+#include "pythonic/include/numpy/random/generator.hpp"
+#include "pythonic/include/numpy/random/weibull.hpp"
+
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+#include <random>
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace random
+ {
+
+ template <class pS>
+ types::ndarray<double, pS> weibull(double a, pS const &shape)
+ {
+ types::ndarray<double, pS> result{shape, types::none_type()};
+ std::weibull_distribution<double> distribution{a};
+ std::generate(result.fbegin(), result.fend(),
+ [&]() { return distribution(details::generator); });
+ return result;
+ }
+
+ inline auto weibull(double a, long size)
+ -> decltype(weibull(a, types::array<long, 1>{{size}}))
+ {
+
+ return weibull(a, types::array<long, 1>{{size}});
+ }
+
+ inline double weibull(double a, types::none_type d)
+ {
+ return std::weibull_distribution<double>{a}(details::generator);
+ }
+ } // namespace random
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ravel.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ravel.hpp
new file mode 100644
index 00000000000..ae5b256f54c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ravel.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_NUMPY_RAVEL_HPP
+#define PYTHONIC_NUMPY_RAVEL_HPP
+
+#include "pythonic/include/numpy/ravel.hpp"
+
+#include "pythonic/numpy/ndarray/reshape.hpp"
+#include "pythonic/utils/numpy_conversion.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS>
+ types::ndarray<T, types::pshape<long>>
+ ravel(types::ndarray<T, pS> const &expr)
+ {
+ return expr.reshape(types::pshape<long>{expr.flat_size()});
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(ravel);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/reciprocal.hpp b/contrib/python/pythran/pythran/pythonic/numpy/reciprocal.hpp
new file mode 100644
index 00000000000..8d2286fc268
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/reciprocal.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_NUMPY_RECIPROCAL_HPP
+#define PYTHONIC_NUMPY_RECIPROCAL_HPP
+
+#include "pythonic/include/numpy/reciprocal.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME reciprocal
+#define NUMPY_NARY_FUNC_SYM wrapper::reciprocal
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/remainder.hpp b/contrib/python/pythran/pythran/pythonic/numpy/remainder.hpp
new file mode 100644
index 00000000000..cd7e8b683c2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/remainder.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_NUMPY_REMAINDER_HPP
+#define PYTHONIC_NUMPY_REMAINDER_HPP
+
+#include "pythonic/include/numpy/remainder.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME remainder
+#define NUMPY_NARY_FUNC_SYM wrapper::remainder
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/remainder/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/remainder/accumulate.hpp
new file mode 100644
index 00000000000..d84b55f2208
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/remainder/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_REMAINDER_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_REMAINDER_ACCUMULATE_HPP
+
+#define UFUNC_NAME remainder
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/repeat.hpp b/contrib/python/pythran/pythran/pythonic/numpy/repeat.hpp
new file mode 100644
index 00000000000..5ea1085dac6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/repeat.hpp
@@ -0,0 +1,54 @@
+#ifndef PYTHONIC_NUMPY_REPEAT_HPP
+#define PYTHONIC_NUMPY_REPEAT_HPP
+
+#include "pythonic/include/numpy/repeat.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_conversion.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/builtins/None.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ repeat(types::ndarray<T, pS> const &expr, long repeats, long axis)
+ {
+ constexpr auto N = std::tuple_size<pS>::value;
+ if (axis < 0)
+ axis += N;
+
+ auto shape = sutils::getshape(expr);
+ const long stride = std::accumulate(shape.begin() + axis + 1, shape.end(),
+ 1L, std::multiplies<long>());
+ shape[axis] *= repeats;
+
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>> out(
+ shape, builtins::None);
+ auto out_iter = out.fbegin();
+ for (auto iter = expr.fbegin(), end = expr.fend(); iter != end;
+ iter += stride)
+ for (int i = 0; i < repeats; ++i)
+ out_iter = std::copy(iter, iter + stride, out_iter);
+ return out;
+ }
+ template <class T, class pS>
+ types::ndarray<T, types::pshape<long>>
+ repeat(types::ndarray<T, pS> const &expr, long repeats, types::none_type axis)
+ {
+ types::ndarray<T, types::pshape<long>> out(
+ types::pshape<long>{expr.flat_size() * repeats}, builtins::None);
+ auto out_iter = out.fbegin();
+ for (auto iter = expr.fbegin(), end = expr.fend(); iter != end; ++iter)
+ for (int i = 0; i < repeats; ++i)
+ *out_iter++ = *iter;
+ return out;
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(repeat);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/resize.hpp b/contrib/python/pythran/pythran/pythonic/numpy/resize.hpp
new file mode 100644
index 00000000000..2a247c516b4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/resize.hpp
@@ -0,0 +1,9 @@
+#ifndef PYTHONIC_NUMPY_RESIZE_HPP
+#define PYTHONIC_NUMPY_RESIZE_HPP
+
+#include "pythonic/include/numpy/resize.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/numpy/ndarray/reshape.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/right_shift.hpp b/contrib/python/pythran/pythran/pythonic/numpy/right_shift.hpp
new file mode 100644
index 00000000000..bf81419626c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/right_shift.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_NUMPY_RIGHTSHIFT_HPP
+#define PYTHONIC_NUMPY_RIGHTSHIFT_HPP
+
+#include "pythonic/include/numpy/right_shift.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+#include "pythonic/operator_/rshift.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME right_shift
+#define NUMPY_NARY_FUNC_SYM operator_::rshift
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/right_shift/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/right_shift/accumulate.hpp
new file mode 100644
index 00000000000..32173f5bbf0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/right_shift/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_RIGHT_SHIFT_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_RIGHT_SHIFT_ACCUMULATE_HPP
+
+#define UFUNC_NAME right_shift
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/rint.hpp b/contrib/python/pythran/pythran/pythonic/numpy/rint.hpp
new file mode 100644
index 00000000000..8fe7e613507
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/rint.hpp
@@ -0,0 +1,33 @@
+#ifndef PYTHONIC_NUMPY_RINT_HPP
+#define PYTHONIC_NUMPY_RINT_HPP
+
+#include "pythonic/include/numpy/rint.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace wrapper
+ {
+ template <class T>
+ T rint(T const &v)
+ {
+ return std::nearbyint(v);
+ }
+ template <class T>
+ std::complex<T> rint(std::complex<T> const &v)
+ {
+ return {std::nearbyint(v.real()), std::nearbyint(v.imag())};
+ }
+ }
+#define NUMPY_NARY_FUNC_NAME rint
+#define NUMPY_NARY_FUNC_SYM wrapper::rint
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/rollaxis.hpp b/contrib/python/pythran/pythran/pythonic/numpy/rollaxis.hpp
new file mode 100644
index 00000000000..3c034b0e1bf
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/rollaxis.hpp
@@ -0,0 +1,43 @@
+#ifndef PYTHONIC_NUMPY_ROLLAXIS_HPP
+#define PYTHONIC_NUMPY_ROLLAXIS_HPP
+
+#include "pythonic/include/numpy/rollaxis.hpp"
+
+#include "pythonic/numpy/transpose.hpp"
+#include "pythonic/numpy/copy.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ rollaxis(types::ndarray<T, pS> const &a, long axis, long start)
+ {
+ long constexpr N = std::tuple_size<pS>::value;
+ long t[N];
+ if (start >= axis) {
+ for (long i = 0; i < axis; ++i)
+ t[i] = i;
+ for (long i = axis + 1; i < start; ++i)
+ t[i - 1] = i;
+ t[start - 1] = axis;
+ for (long i = start; i < N; ++i)
+ t[i] = i;
+ } else {
+ for (long i = 0; i < start; ++i)
+ t[i] = i;
+ t[start] = axis;
+ for (long i = start + 1; i <= axis; ++i)
+ t[i] = i - 1;
+ for (long i = axis + 1, n = N; i < n; ++i)
+ t[i] = i;
+ }
+ return _transposer(a, t);
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(rollaxis);
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/rot90.hpp b/contrib/python/pythran/pythran/pythonic/numpy/rot90.hpp
new file mode 100644
index 00000000000..584ed5229c4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/rot90.hpp
@@ -0,0 +1,46 @@
+#ifndef PYTHONIC_NUMPY_ROT90_HPP
+#define PYTHONIC_NUMPY_ROT90_HPP
+
+#include "pythonic/include/numpy/rot90.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_conversion.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/numpy/copy.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS>
+ types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>
+ rot90(types::ndarray<T, pS> const &expr, int k)
+ {
+ auto constexpr N = std::tuple_size<pS>::value;
+ if (k % 4 == 0)
+ return copy(expr);
+ types::array<long, N> shape = sutils::getshape(expr);
+ if (k % 4 != 2)
+ std::swap(shape[0], shape[1]);
+ types::ndarray<T, types::array<long, N>> out(shape, builtins::None);
+ if (k % 4 == 1) {
+ for (int i = 0; i < shape[1]; ++i)
+ for (int j = 0; j < shape[0]; ++j)
+ out[shape[0] - 1 - j][i] = expr[i][j];
+ } else if (k % 4 == 2) {
+ for (int i = 0; i < shape[1]; ++i)
+ for (int j = 0; j < shape[0]; ++j)
+ out[shape[0] - 1 - j][shape[1] - 1 - i] = expr[j][i];
+ } else {
+ for (int i = 0; i < shape[1]; ++i)
+ for (int j = 0; j < shape[0]; ++j)
+ out[j][shape[1] - 1 - i] = expr[i][j];
+ }
+ return out;
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(rot90)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/round.hpp b/contrib/python/pythran/pythran/pythonic/numpy/round.hpp
new file mode 100644
index 00000000000..e2e97a610b8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/round.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_ROUND_HPP
+#define PYTHONIC_NUMPY_ROUND_HPP
+
+#include "pythonic/include/numpy/round.hpp"
+#include "pythonic/numpy/around.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/round_.hpp b/contrib/python/pythran/pythran/pythonic/numpy/round_.hpp
new file mode 100644
index 00000000000..3fadd160511
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/round_.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_ROUND__HPP
+#define PYTHONIC_NUMPY_ROUND__HPP
+
+#include "pythonic/include/numpy/round_.hpp"
+#include "pythonic/numpy/around.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/searchsorted.hpp b/contrib/python/pythran/pythran/pythonic/numpy/searchsorted.hpp
new file mode 100644
index 00000000000..3346ca06ce9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/searchsorted.hpp
@@ -0,0 +1,91 @@
+#ifndef PYTHONIC_NUMPY_SEARCHSORTED_HPP
+#define PYTHONIC_NUMPY_SEARCHSORTED_HPP
+
+#include "pythonic/include/numpy/searchsorted.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_conversion.hpp"
+#include "pythonic/utils/int_.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/str.hpp"
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/builtins/ValueError.hpp"
+#include "pythonic/numpy/asarray.hpp"
+
+#include <algorithm>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace details
+ {
+ template <class T, class U>
+ long searchsorted(U const &a, T const &v, bool left)
+ {
+ if (left)
+ return std::lower_bound(a.begin(), a.end(), v) - a.begin();
+ else
+ return std::upper_bound(a.begin(), a.end(), v) - a.begin();
+ }
+
+ bool issearchsortedleft(types::str const &side)
+ {
+ if (side[0] == "l")
+ return true;
+ else if (side[0] == "r")
+ return false;
+ else
+ throw types::ValueError("'" + side +
+ "' is an invalid value for keyword 'side'");
+ }
+ }
+
+ template <class T, class U>
+ typename std::enable_if<!types::is_numexpr_arg<T>::value, long>::type
+ searchsorted(U const &a, T const &v, types::str const &side)
+ {
+ bool left = details::issearchsortedleft(side);
+ return details::searchsorted(a, v, left);
+ }
+
+ namespace
+ {
+ template <class E, class I0, class I1>
+ void _search_sorted(E const &a, I0 ibegin, I0 iend, I1 obegin, bool left,
+ utils::int_<1>)
+ {
+ for (; ibegin != iend; ++ibegin, ++obegin)
+ *obegin = details::searchsorted(a, *ibegin, left);
+ }
+
+ template <class E, class I0, class I1, size_t N>
+ void _search_sorted(E const &a, I0 ibegin, I0 iend, I1 obegin, bool left,
+ utils::int_<N>)
+ {
+ for (; ibegin != iend; ++ibegin, ++obegin)
+ _search_sorted(a, (*ibegin).begin(), (*ibegin).end(), (*obegin).begin(),
+ left, utils::int_<N - 1>());
+ }
+ }
+
+ template <class E, class T>
+ typename std::enable_if<
+ types::is_numexpr_arg<E>::value,
+ types::ndarray<long, types::array<long, E::value>>>::type
+ searchsorted(T const &a, E const &v, types::str const &side)
+ {
+ static_assert(T::value == 1,
+ "Not Implemented : searchsorted for dimension != 1");
+ bool left = details::issearchsortedleft(side);
+
+ types::ndarray<long, types::array<long, E::value>> out(asarray(v)._shape,
+ builtins::None);
+ _search_sorted(a, v.begin(), v.end(), out.begin(), left,
+ utils::int_<E::value>());
+ return out;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/select.hpp b/contrib/python/pythran/pythran/pythonic/numpy/select.hpp
new file mode 100644
index 00000000000..0d76091acd3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/select.hpp
@@ -0,0 +1,123 @@
+#ifndef PYTHONIC_NUMPY_SELECT_HPP
+#define PYTHONIC_NUMPY_SELECT_HPP
+
+#include "pythonic/include/numpy/select.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/int_.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace
+ {
+ // TODO It could certainly be represent as a numpy_***_expr as each
+ // elements
+ // is computed without information from neighbor.
+ //
+ template <class Ichoice, class Icond, class Iout, class Isel>
+ long _select(Ichoice ibegin, Ichoice iend, Iout obegin, Isel sbegin,
+ Icond cbegin, long size, utils::int_<1>)
+ {
+ static_assert(std::is_same<Ichoice, int>::value, "");
+ for (; ibegin != iend && size != 0;
+ ++ibegin, ++obegin, ++sbegin, ++cbegin) {
+ // If elements it not already selected && condition match, copy it!
+ if (!*sbegin && *cbegin) {
+ *obegin = *ibegin;
+ *sbegin = true;
+ size--;
+ }
+ }
+ return size;
+ }
+
+ template <class Ichoice, class Icond, class Iout, class Isel, size_t N>
+ long _select(Ichoice ibegin, Ichoice iend, Iout obegin, Isel sbegin,
+ Icond cbegin, long size, utils::int_<N>)
+ {
+ for (; ibegin != iend && size != 0;
+ ++ibegin, ++obegin, ++sbegin, ++cbegin)
+ size = _select((*ibegin).begin(), (*ibegin).end(), (*obegin).begin(),
+ (*sbegin).begin(), (*cbegin).begin(), size,
+ utils::int_<N - 1>());
+ return size;
+ }
+ }
+
+ template <class C, class L>
+ types::ndarray<typename L::dtype, types::array<long, L::value - 1>>
+ select(C const &condlist, L const &choicelist, typename L::dtype _default)
+ {
+ constexpr size_t N = L::value - 1;
+ auto &&choicelist0_shape = sutils::getshape(choicelist[0]);
+ types::ndarray<typename L::dtype, types::array<long, N>> out(
+ choicelist0_shape, _default);
+ types::ndarray<typename L::dtype, types::array<long, N>> selected(
+ choicelist0_shape, false);
+ long size = selected.flat_size();
+ for (long i = 0; i < condlist.size() && size != 0; i++)
+ size =
+ _select(choicelist[i].begin(), choicelist[i].end(), out.begin(),
+ selected.begin(), condlist.begin(), size, utils::int_<N>());
+ return out;
+ }
+
+ template <class C, class L, class T>
+ types::ndarray<typename L::dtype, sutils::pop_head_t<typename L::shape_t>>
+ select_helper(C const &condlist, L const &choicelist, T _default)
+ {
+ types::ndarray<typename L::dtype, sutils::pop_head_t<typename L::shape_t>>
+ out(sutils::getshape(choicelist[0]), _default);
+ for (long i = 0; i < out.flat_size(); ++i)
+ for (long j = 0; j < (long)condlist.size(); ++j)
+ if (condlist[j].buffer[i]) {
+ out.buffer[i] = choicelist[j].buffer[i];
+ break;
+ }
+ return out;
+ }
+
+ template <class T, class TpS, class U, class UpS>
+ typename std::enable_if<std::tuple_size<TpS>::value ==
+ std::tuple_size<UpS>::value,
+ types::ndarray<T, TpS>>::type
+ select(types::list<types::ndarray<U, UpS>> const &condlist,
+ types::list<types::ndarray<T, TpS>> const &choicelist, T _default)
+ {
+ return select_helper(condlist, choicelist, _default);
+ }
+ template <class T, class TpS, class U, class UpS, size_t M>
+ typename std::enable_if<std::tuple_size<TpS>::value ==
+ std::tuple_size<UpS>::value,
+ types::ndarray<T, TpS>>::type
+ select(types::static_list<types::ndarray<U, UpS>, M> const &condlist,
+ types::static_list<types::ndarray<T, TpS>, M> const &choicelist,
+ T _default)
+ {
+ return select_helper(condlist, choicelist, _default);
+ }
+ template <class T, class TpS, class U, class UpS, size_t M>
+ typename std::enable_if<std::tuple_size<TpS>::value ==
+ std::tuple_size<UpS>::value,
+ types::ndarray<T, TpS>>::type
+ select(types::static_list<types::ndarray<U, UpS>, M> const &condlist,
+ types::list<types::ndarray<T, TpS>> const &choicelist, T _default)
+ {
+ return select_helper(condlist, choicelist, _default);
+ }
+ template <class T, class TpS, class U, class UpS, size_t M>
+ typename std::enable_if<std::tuple_size<TpS>::value ==
+ std::tuple_size<UpS>::value,
+ types::ndarray<T, TpS>>::type
+ select(types::list<types::ndarray<U, UpS>> const &condlist,
+ types::static_list<types::ndarray<T, TpS>, M> const &choicelist,
+ T _default)
+ {
+ return select_helper(condlist, choicelist, _default);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/setdiff1d.hpp b/contrib/python/pythran/pythran/pythonic/numpy/setdiff1d.hpp
new file mode 100644
index 00000000000..0325efcc435
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/setdiff1d.hpp
@@ -0,0 +1,88 @@
+#ifndef PYTHONIC_NUMPY_SETDIFF1D_HPP
+#define PYTHONIC_NUMPY_SETDIFF1D_HPP
+
+#include "pythonic/include/numpy/setdiff1d.hpp"
+
+#include "pythonic/numpy/asarray.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/allocate.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/pdqsort.hpp"
+
+#include <algorithm>
+#include <set>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace impl
+ {
+
+ template <typename InputIterator1, typename InputIterator2,
+ typename OutputIterator>
+ OutputIterator
+ set_difference_unique(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, InputIterator2 last2,
+ OutputIterator result)
+ {
+ while (first1 != last1 && first2 != last2) {
+ auto const t1 = *first1;
+ auto const t2 = *first2;
+ if (t1 < t2) {
+ *result = t1;
+ while (*++first1 == t1)
+ ;
+ ++result;
+ } else if (t2 < t1)
+ while (*++first2 == t2)
+ ;
+ else {
+ while (*++first1 == t1)
+ ;
+ while (*++first2 == t2)
+ ;
+ }
+ }
+ while (first1 != last1) {
+ auto const t1 = *first1;
+ *result = t1;
+ while (*++first1 == t1)
+ ;
+ ++result;
+ }
+ return result;
+ }
+ } // namespace impl
+
+ template <class T, class U>
+ types::ndarray<typename __combined<typename types::dtype_of<T>::type,
+ typename types::dtype_of<U>::type>::type,
+ types::pshape<long>>
+ setdiff1d(T const &ar1, U const &ar2, bool assume_unique)
+ {
+ using dtype = typename __combined<typename types::dtype_of<T>::type,
+ typename types::dtype_of<U>::type>::type;
+ auto far1 = numpy::functor::array{}(ar1);
+ auto far2 = numpy::functor::array{}(ar2);
+
+ pdqsort(far1.fbegin(), far1.fend());
+ pdqsort(far2.fbegin(), far2.fend());
+ dtype *out = utils::allocate<dtype>(far1.flat_size() * far2.flat_size());
+
+ dtype *out_last;
+ if (assume_unique) {
+ out_last = std::set_difference(far1.fbegin(), far1.fend(), far2.fbegin(),
+ far2.fend(), out);
+ } else {
+ out_last = impl::set_difference_unique(far1.fbegin(), far1.fend(),
+ far2.fbegin(), far2.fend(), out);
+ }
+ auto size = out_last - out;
+ out = utils::reallocate(out, size);
+ return {out, types::pshape<long>(size), types::ownership::owned};
+ }
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/shape.hpp b/contrib/python/pythran/pythran/pythonic/numpy/shape.hpp
new file mode 100644
index 00000000000..630e53aa229
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/shape.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_NUMPY_SHAPE_HPP
+#define PYTHONIC_NUMPY_SHAPE_HPP
+
+#include "pythonic/include/numpy/shape.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class T, class pS>
+ auto shape(types::ndarray<T, pS> const &e) -> decltype(e._shape)
+ {
+ return e._shape;
+ }
+
+ template <class E>
+ auto shape(E const &e) -> decltype(sutils::getshape(e))
+ {
+ return sutils::getshape(e);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/short_.hpp b/contrib/python/pythran/pythran/pythonic/numpy/short_.hpp
new file mode 100644
index 00000000000..a4e9b5dd8f1
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/short_.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_NUMPY_SHORT__HPP
+#define PYTHONIC_NUMPY_SHORT__HPP
+
+#include "pythonic/include/numpy/short_.hpp"
+
+#include "pythonic/types/numpy_op_helper.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/meta.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ inline short short_()
+ {
+ return {};
+ }
+
+ template <class V>
+ short short_(V v)
+ {
+ return v;
+ }
+ } // namespace details
+
+#define NUMPY_NARY_FUNC_NAME short_
+#define NUMPY_NARY_FUNC_SYM details::short_
+#include "pythonic/types/numpy_nary_expr.hpp"
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/sign.hpp b/contrib/python/pythran/pythran/pythonic/numpy/sign.hpp
new file mode 100644
index 00000000000..0cac69d2d24
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/sign.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_NUMPY_SIGN_HPP
+#define PYTHONIC_NUMPY_SIGN_HPP
+
+#include "pythonic/include/numpy/sign.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME sign
+#define NUMPY_NARY_FUNC_SYM details::sign
+#include "pythonic/types/numpy_nary_expr.hpp"
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/signbit.hpp b/contrib/python/pythran/pythran/pythonic/numpy/signbit.hpp
new file mode 100644
index 00000000000..1111800428c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/signbit.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_NUMPY_SIGNBIT_HPP
+#define PYTHONIC_NUMPY_SIGNBIT_HPP
+
+#include "pythonic/include/numpy/signbit.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+#define NUMPY_NARY_FUNC_NAME signbit
+#define NUMPY_NARY_FUNC_SYM details::signbit
+#include "pythonic/types/numpy_nary_expr.hpp"
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/sinh.hpp b/contrib/python/pythran/pythran/pythonic/numpy/sinh.hpp
new file mode 100644
index 00000000000..be22034ec83
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/sinh.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_NUMPY_SINH_HPP
+#define PYTHONIC_NUMPY_SINH_HPP
+
+#include "pythonic/include/numpy/sinh.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME sinh
+#define NUMPY_NARY_FUNC_SYM xsimd::sinh
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/size.hpp b/contrib/python/pythran/pythran/pythonic/numpy/size.hpp
new file mode 100644
index 00000000000..813bc257e3b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/size.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_NUMPY_SIZE_HPP
+#define PYTHONIC_NUMPY_SIZE_HPP
+
+#include "pythonic/include/numpy/size.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class E>
+ auto size(E const &e) -> decltype(e.flat_size())
+ {
+ return e.flat_size();
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/sometrue.hpp b/contrib/python/pythran/pythran/pythonic/numpy/sometrue.hpp
new file mode 100644
index 00000000000..ff0ab9357f1
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/sometrue.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_SOMETRUE_HPP
+#define PYTHONIC_NUMPY_SOMETRUE_HPP
+
+#include "pythonic/include/numpy/sometrue.hpp"
+#include "pythonic/numpy/any.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/sort_complex.hpp b/contrib/python/pythran/pythran/pythonic/numpy/sort_complex.hpp
new file mode 100644
index 00000000000..3bb53b2837d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/sort_complex.hpp
@@ -0,0 +1,9 @@
+#ifndef PYTHONIC_NUMPY_SORTCOMPLEX_HPP
+#define PYTHONIC_NUMPY_SORTCOMPLEX_HPP
+
+#include "pythonic/include/numpy/sort_complex.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/numpy/sort.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/spacing.hpp b/contrib/python/pythran/pythran/pythonic/numpy/spacing.hpp
new file mode 100644
index 00000000000..11bb465f6a3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/spacing.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_NUMPY_SPACING_HPP
+#define PYTHONIC_NUMPY_SPACING_HPP
+
+#include "pythonic/include/numpy/spacing.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME spacing
+#define NUMPY_NARY_FUNC_SYM wrapper::spacing
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/split.hpp b/contrib/python/pythran/pythran/pythonic/numpy/split.hpp
new file mode 100644
index 00000000000..03436e9d7d6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/split.hpp
@@ -0,0 +1,41 @@
+#ifndef PYTHONIC_NUMPY_SPLIT_HPP
+#define PYTHONIC_NUMPY_SPLIT_HPP
+
+#include "pythonic/include/numpy/split.hpp"
+
+#include "pythonic/numpy/array_split.hpp"
+#include "pythonic/builtins/ValueError.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS>
+ types::list<types::ndarray<T, types::array<long, std::tuple_size<pS>::value>>>
+ split(types::ndarray<T, pS> const &a, long nb_split)
+ {
+ if (a.flat_size() % nb_split != 0)
+ throw types::ValueError("array split does ! result in an equal division");
+ return array_split(a, nb_split);
+ }
+
+ template <class T, class pS, class I>
+ typename std::enable_if<
+ types::is_iterable<I>::value,
+ types::list<types::ndarray<
+ T, types::array<long, std::tuple_size<pS>::value>>>>::type
+ split(types::ndarray<T, pS> const &a, I const &split_mask)
+ {
+ return array_split(a, split_mask);
+ }
+
+ template <class E, class I>
+ types::list<types::ndarray<typename E::dtype, types::array<long, E::value>>>
+ split(E const &a, I const &)
+ {
+ throw std::runtime_error("split only partially implemented");
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/stack.hpp b/contrib/python/pythran/pythran/pythonic/numpy/stack.hpp
new file mode 100644
index 00000000000..f5a6b96856c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/stack.hpp
@@ -0,0 +1,72 @@
+#ifndef PYTHONIC_NUMPY_STACK_HPP
+#define PYTHONIC_NUMPY_STACK_HPP
+
+#include "pythonic/builtins/len.hpp"
+#include "pythonic/builtins/ValueError.hpp"
+#include <pythonic/include/numpy/stack.hpp>
+#include <pythonic/numpy/concatenate.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class ArraySequence>
+ types::ndarray<typename ArraySequence::value_type::dtype,
+ types::array<long, ArraySequence::value_type::value + 1>>
+ stack(ArraySequence const &args, long axis)
+ {
+ if (builtins::len(args) == 0)
+ throw pythonic::types::ValueError("need at least one array to stack");
+ auto shape = sutils::getshape(args[0]);
+ constexpr long N = std::tuple_size<decltype(
+ shape)>::value; // The length of the shape array.
+ auto values = sutils::array(
+ shape); // You can't do shape[i] but you can do shape.array()[i]
+ types::array<long, N + 1>
+ new_shape; // A new array that's 1 element longer than shape.
+ // Insert a "0" at the position indicated by axis.
+ for (long i = 0; i < N + 1; i++) {
+ if (i < axis)
+ new_shape[i] = values[i];
+ if (i == axis)
+ new_shape[i] = 1;
+ if (i > axis)
+ new_shape[i] = values[i - 1];
+ }
+
+ // Create a new empty list.
+ types::list<types::ndarray<
+ typename ArraySequence::value_type::dtype,
+ types::array<long, ArraySequence::value_type::value + 1>>> bi(0);
+ // Push the resized arrays into the list.
+ for (auto &&arg : args) {
+ bi.push_back(arg.reshape(new_shape));
+ }
+ // Call concatenate on this list.
+ return concatenate(bi, axis);
+ }
+ template <size_t... Is, class... Tys>
+ types::ndarray<typename details::stack_helper_t<Tys...>::dtype,
+ types::array<long, details::stack_helper_t<Tys...>::value + 1>>
+ stack(std::tuple<Tys...> const &args, long axis, utils::index_sequence<Is...>)
+ {
+ types::array<
+ types::ndarray<
+ typename details::stack_helper_t<Tys...>::dtype,
+ types::array<long, details::stack_helper_t<Tys...>::value>>,
+ sizeof...(Tys)> vargs{{std::get<Is>(args)...}};
+ return stack(vargs, axis);
+ }
+
+ template <class... Tys>
+ types::ndarray<typename details::stack_helper_t<Tys...>::dtype,
+ types::array<long, details::stack_helper_t<Tys...>::value + 1>>
+ stack(std::tuple<Tys...> const &args, long axis)
+ {
+ return stack(args, axis, utils::make_index_sequence<sizeof...(Tys)>());
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/std_.hpp b/contrib/python/pythran/pythran/pythonic/numpy/std_.hpp
new file mode 100644
index 00000000000..5ff8a402c78
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/std_.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_NUMPY_STD_HPP
+#define PYTHONIC_NUMPY_STD_HPP
+
+#include "pythonic/include/numpy/std_.hpp"
+#include "pythonic/numpy/var.hpp"
+#include "pythonic/numpy/sqrt.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class... Args>
+ auto std_(Args &&... args)
+ -> decltype(functor::sqrt{}(var(std::forward<Args>(args)...)))
+ {
+ return functor::sqrt{}(var(std::forward<Args>(args)...));
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/subtract.hpp b/contrib/python/pythran/pythran/pythonic/numpy/subtract.hpp
new file mode 100644
index 00000000000..335aff7424f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/subtract.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_NUMPY_SUBTRACT_HPP
+#define PYTHONIC_NUMPY_SUBTRACT_HPP
+
+#include "pythonic/include/numpy/subtract.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/operator_/sub.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME subtract
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::sub
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/subtract/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/subtract/accumulate.hpp
new file mode 100644
index 00000000000..20b5a8ff2e3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/subtract/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_SUBTRACT_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_SUBTRACT_ACCUMULATE_HPP
+
+#define UFUNC_NAME subtract
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/swapaxes.hpp b/contrib/python/pythran/pythran/pythonic/numpy/swapaxes.hpp
new file mode 100644
index 00000000000..0148bfde460
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/swapaxes.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_NUMPY_SWAPAXES_HPP
+#define PYTHONIC_NUMPY_SWAPAXES_HPP
+
+#include "pythonic/include/numpy/swapaxes.hpp"
+
+#include "pythonic/numpy/transpose.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T>
+ auto swapaxes(T &&a, int axis1, int axis2) -> decltype(functor::transpose{}(
+ std::forward<T>(a),
+ std::declval<types::array<long, std::decay<T>::type::value>>()))
+ {
+ constexpr long N = std::decay<T>::type::value;
+ types::array<long, N> t;
+ for (unsigned long i = 0; i < N; ++i)
+ t[i] = i;
+ std::swap(t[axis1], t[axis2]);
+ return functor::transpose{}(std::forward<T>(a), t);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/take.hpp b/contrib/python/pythran/pythran/pythonic/numpy/take.hpp
new file mode 100644
index 00000000000..ed39c7cc9b8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/take.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_NUMPY_TAKE_HPP
+#define PYTHONIC_NUMPY_TAKE_HPP
+
+#include "pythonic/include/numpy/take.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class F, class T>
+ auto take(T &&expr, F &&indices)
+ -> decltype(std::forward<T>(expr)[std::forward<T>(indices)])
+ {
+ return expr[indices];
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/tan.hpp b/contrib/python/pythran/pythran/pythonic/numpy/tan.hpp
new file mode 100644
index 00000000000..fb53ab091b8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/tan.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_NUMPY_TAN_HPP
+#define PYTHONIC_NUMPY_TAN_HPP
+
+#include "pythonic/include/numpy/tan.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME tan
+#define NUMPY_NARY_FUNC_SYM xsimd::tan
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/tanh.hpp b/contrib/python/pythran/pythran/pythonic/numpy/tanh.hpp
new file mode 100644
index 00000000000..e2bb22c7fab
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/tanh.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_NUMPY_TANH_HPP
+#define PYTHONIC_NUMPY_TANH_HPP
+
+#include "pythonic/include/numpy/tanh.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME tanh
+#define NUMPY_NARY_FUNC_SYM xsimd::tanh
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/tile.hpp b/contrib/python/pythran/pythran/pythonic/numpy/tile.hpp
new file mode 100644
index 00000000000..2eb0a52f442
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/tile.hpp
@@ -0,0 +1,79 @@
+#ifndef PYTHONIC_NUMPY_TILE_HPP
+#define PYTHONIC_NUMPY_TILE_HPP
+
+#include "pythonic/include/numpy/tile.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace
+ {
+ template <class I, class O>
+ void _tile(I begin, I end, O &out, long rep, utils::int_<1>)
+ {
+ for (long i = 0; i < rep; ++i)
+ out = std::copy(begin, end, out);
+ }
+
+ template <class I, class O, size_t N>
+ void _tile(I begin, I end, O &out, long rep, utils::int_<N>)
+ {
+ for (; begin != end; ++begin)
+ _tile((*begin).begin(), (*begin).end(), out, rep, utils::int_<N - 1>());
+ }
+ }
+
+ template <class E>
+ types::ndarray<typename E::dtype, types::array<long, E::value>>
+ tile(E const &expr, long reps)
+ {
+ size_t n = expr.flat_size();
+ types::ndarray<typename E::dtype, types::array<long, E::value>> out(
+ types::array<long, 1>{{long(n * reps)}}, builtins::None);
+ auto out_iter = out.fbegin();
+ _tile(expr.begin(), expr.end(), out_iter, 1, utils::int_<E::value>());
+ for (long i = 1; i < reps; ++i)
+ out_iter = std::copy(out.fbegin(), out.fbegin() + n, out_iter);
+ return out;
+ }
+
+ template <size_t Shift, class R, class S, size_t... Is>
+ types::array<long, sizeof...(Is)>
+ tile_init_shape(R const &reps, S const &expr_shape,
+ utils::index_sequence<Is...>)
+ {
+ constexpr size_t M = S::value;
+ return {
+ {(reps[Is] * ((Is < Shift) ? 1 : expr_shape.template shape < (Is < M)
+ ? Is
+ : 0 > ()))...}};
+ }
+
+ template <class E, size_t N>
+ types::ndarray<typename E::dtype, types::array<long, N>>
+ tile(E const &expr, types::array<long, N> const &reps)
+ {
+ size_t n = expr.flat_size();
+ types::array<long, N> shape = tile_init_shape<N - E::value>(
+ reps, expr, utils::make_index_sequence<N>());
+
+ long last_rep = (E::value == N) ? std::get<N - 1>(reps) : 1;
+ types::ndarray<typename E::dtype, types::array<long, N>> out(
+ shape, builtins::None);
+ auto out_iter = out.fbegin();
+ _tile(expr.begin(), expr.end(), out_iter, last_rep,
+ utils::int_<E::value>());
+
+ size_t nreps = out.flat_size() / (n * last_rep);
+ for (size_t i = 1; i < nreps; ++i)
+ out_iter = std::copy(out.fbegin(), out.fbegin() + n, out_iter);
+ return out;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/trace.hpp b/contrib/python/pythran/pythran/pythonic/numpy/trace.hpp
new file mode 100644
index 00000000000..2677331529c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/trace.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_NUMPY_TRACE_HPP
+#define PYTHONIC_NUMPY_TRACE_HPP
+
+#include "pythonic/include/numpy/trace.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class T>
+ typename T::dtype trace(T const &expr, int offset)
+ {
+ static_assert(T::value == 2, "Not Implemented : Trace for dimension != 2");
+
+ typename T::dtype res = 0;
+ long y_offset = std::max(-offset, 0);
+ long x_offset = std::max(0, offset);
+ long size = std::min(expr.flat_size() - y_offset,
+ expr.fast(0).flat_size() - x_offset);
+ if (offset < 0)
+ for (long i = 0; i < size; i++)
+ res += expr.fast(i + offset).fast(i);
+ else if (offset > 0)
+ for (long i = 0; i < size; i++)
+ res += expr.fast(i).fast(i + offset);
+ else
+ for (long i = 0; i < size; i++)
+ res += expr.fast(i).fast(i);
+ return res;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/tri.hpp b/contrib/python/pythran/pythran/pythonic/numpy/tri.hpp
new file mode 100644
index 00000000000..fb39c9ca58f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/tri.hpp
@@ -0,0 +1,30 @@
+#ifndef PYTHONIC_NUMPY_TRI_HPP
+#define PYTHONIC_NUMPY_TRI_HPP
+
+#include "pythonic/include/numpy/tri.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class dtype>
+ types::ndarray<typename dtype::type, types::pshape<long, long>>
+ tri(long N, long M, long k, dtype d)
+ {
+ if (M == -1)
+ M = N;
+ types::ndarray<typename dtype::type, types::pshape<long, long>> out(
+ types::pshape<long, long>{N, M}, 0);
+ for (int i = 0; i < N; ++i)
+ for (long j = 0; j < M; ++j)
+ if (j - i <= k)
+ out[i][j] = 1;
+ return out;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/tril.hpp b/contrib/python/pythran/pythran/pythonic/numpy/tril.hpp
new file mode 100644
index 00000000000..d6e9a12d5da
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/tril.hpp
@@ -0,0 +1,34 @@
+#ifndef PYTHONIC_NUMPY_TRIL_HPP
+#define PYTHONIC_NUMPY_TRIL_HPP
+
+#include "pythonic/include/numpy/tril.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_conversion.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS>
+ types::ndarray<T, pS> tril(types::ndarray<T, pS> const &expr, int k)
+ {
+ types::ndarray<T, pS> out(expr._shape, builtins::None);
+ for (int i = 0; i < std::get<0>(expr._shape); ++i) {
+ auto out_i = out[i];
+ auto expr_i = expr[i];
+ for (long j = 0; j < std::get<1>(expr._shape); ++j)
+ if (j - i <= k)
+ out_i[j] = expr_i[j];
+ else
+ out_i[j] = 0;
+ }
+ return out;
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(tril)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/trim_zeros.hpp b/contrib/python/pythran/pythran/pythonic/numpy/trim_zeros.hpp
new file mode 100644
index 00000000000..89b8be558ad
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/trim_zeros.hpp
@@ -0,0 +1,34 @@
+#ifndef PYTHONIC_NUMPY_TRIMZEROS_HPP
+#define PYTHONIC_NUMPY_TRIMZEROS_HPP
+
+#include "pythonic/include/numpy/trim_zeros.hpp"
+
+#include "pythonic/types/numpy_gexpr.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T>
+ types::numpy_gexpr<T, types::cstride_normalized_slice<1>>
+ trim_zeros(T const &expr, types::str const &trim)
+ {
+ static_assert(T::value == 1,
+ "Not implemented : trim_zeroes only works for 1D array");
+
+ long begin = 0;
+ long end = expr.flat_size();
+ if (trim.find("f") != -1)
+ begin = std::find_if(expr.begin(), expr.end(),
+ [](typename T::dtype i) { return i != 0; }) -
+ expr.begin();
+ if (trim.find("b") != -1)
+ while (*(expr.begin() + --end) != 0)
+ ;
+ return make_gexpr(expr, types::fast_contiguous_slice(begin, end));
+ }
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/triu.hpp b/contrib/python/pythran/pythran/pythonic/numpy/triu.hpp
new file mode 100644
index 00000000000..b02116d0aab
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/triu.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_NUMPY_TRIU_HPP
+#define PYTHONIC_NUMPY_TRIU_HPP
+
+#include "pythonic/include/numpy/triu.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_conversion.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <class T, class pS>
+ types::ndarray<T, pS> triu(types::ndarray<T, pS> const &expr, int k)
+ {
+ types::ndarray<T, pS> out(expr._shape, builtins::None);
+ for (int i = 0; i < std::get<0>(expr._shape); ++i)
+ for (long j = 0; j < std::get<1>(expr._shape); ++j)
+ if (j - i >= k)
+ out[i][j] = expr[i][j];
+ else
+ out[i][j] = 0;
+ return out;
+ }
+
+ NUMPY_EXPR_TO_NDARRAY0_IMPL(triu)
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/true_divide.hpp b/contrib/python/pythran/pythran/pythonic/numpy/true_divide.hpp
new file mode 100644
index 00000000000..0aedca78e1a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/true_divide.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_NUMPY_TRUEDIVIDE_HPP
+#define PYTHONIC_NUMPY_TRUEDIVIDE_HPP
+
+#include "pythonic/include/numpy/true_divide.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/numpy_broadcast.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+#include "pythonic/operator_/div.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+// FIXME: this is ! always a true_divide...
+#define NUMPY_NARY_FUNC_NAME true_divide
+#define NUMPY_NARY_FUNC_SYM pythonic::operator_::div
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/true_divide/accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/true_divide/accumulate.hpp
new file mode 100644
index 00000000000..5e6977a899f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/true_divide/accumulate.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_NUMPY_TRUE_DIVIDE_ACCUMULATE_HPP
+#define PYTHONIC_NUMPY_TRUE_DIVIDE_ACCUMULATE_HPP
+
+#define UFUNC_NAME true_divide
+#include "pythonic/numpy/ufunc_accumulate.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/trunc.hpp b/contrib/python/pythran/pythran/pythonic/numpy/trunc.hpp
new file mode 100644
index 00000000000..d5e42e1fb40
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/trunc.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_NUMPY_TRUNC_HPP
+#define PYTHONIC_NUMPY_TRUNC_HPP
+
+#include "pythonic/include/numpy/trunc.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+#define NUMPY_NARY_FUNC_NAME trunc
+#define NUMPY_NARY_FUNC_SYM xsimd::trunc
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ubyte.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ubyte.hpp
new file mode 100644
index 00000000000..67936f26531
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ubyte.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_NUMPY_UBYTE_HPP
+#define PYTHONIC_NUMPY_UBYTE_HPP
+
+#include "pythonic/include/numpy/ubyte.hpp"
+
+#include "pythonic/types/numpy_op_helper.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/meta.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ inline unsigned char ubyte()
+ {
+ return {};
+ }
+
+ template <class V>
+ unsigned char ubyte(V v)
+ {
+ return v;
+ }
+ } // namespace details
+
+#define NUMPY_NARY_FUNC_NAME ubyte
+#define NUMPY_NARY_FUNC_SYM details::ubyte
+#include "pythonic/types/numpy_nary_expr.hpp"
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ufunc_accumulate.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ufunc_accumulate.hpp
new file mode 100644
index 00000000000..295d45b9e3b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ufunc_accumulate.hpp
@@ -0,0 +1,26 @@
+#ifndef UFUNC_NAME
+#error missing UFUNC_NAME
+#endif
+
+// clang-format off
+#include INCLUDE_FILE(pythonic/numpy,UFUNC_NAME)
+// clang-format on
+#include <pythonic/numpy/partial_sum.hpp>
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace numpy
+{
+ namespace UFUNC_NAME
+ {
+ template <class T, class dtype>
+ auto accumulate(T &&a, long axis, dtype d)
+ -> decltype(partial_sum<numpy::functor::UFUNC_NAME>(std::forward<T>(a),
+ axis, d))
+ {
+ return partial_sum<numpy::functor::UFUNC_NAME>(std::forward<T>(a), axis,
+ d);
+ }
+ }
+}
+PYTHONIC_NS_END
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ufunc_reduce.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ufunc_reduce.hpp
new file mode 100644
index 00000000000..400ec350913
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ufunc_reduce.hpp
@@ -0,0 +1,9 @@
+#ifndef UFUNC_INAME
+#error missing UFUNC_INAME
+#endif
+
+// clang-format off
+#include INCLUDE_FILE(pythonic/operator_,UFUNC_INAME)
+// clang-format on
+#include "pythonic/numpy/reduce.hpp"
+#include "pythonic/utils/functor.hpp"
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/uint.hpp b/contrib/python/pythran/pythran/pythonic/numpy/uint.hpp
new file mode 100644
index 00000000000..75e75d28360
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/uint.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_NUMPY_UINT_HPP
+#define PYTHONIC_NUMPY_UINT_HPP
+
+#include "pythonic/include/numpy/uint.hpp"
+
+#include "pythonic/types/numpy_op_helper.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/meta.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ inline unsigned long uint()
+ {
+ return {};
+ }
+
+ template <class V>
+ unsigned long uint(V v)
+ {
+ return v;
+ }
+ } // namespace details
+
+#define NUMPY_NARY_FUNC_NAME uint
+#define NUMPY_NARY_FUNC_SYM details::uint
+#include "pythonic/types/numpy_nary_expr.hpp"
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/uintc.hpp b/contrib/python/pythran/pythran/pythonic/numpy/uintc.hpp
new file mode 100644
index 00000000000..bcb68c5f63f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/uintc.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_NUMPY_UINTC_HPP
+#define PYTHONIC_NUMPY_UINTC_HPP
+
+#include "pythonic/include/numpy/uintc.hpp"
+
+#include "pythonic/types/numpy_op_helper.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/meta.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ inline unsigned uintc()
+ {
+ return {};
+ }
+
+ template <class V>
+ unsigned uintc(V v)
+ {
+ return v;
+ }
+ } // namespace details
+
+#define NUMPY_NARY_FUNC_NAME uintc
+#define NUMPY_NARY_FUNC_SYM details::uintc
+#include "pythonic/types/numpy_nary_expr.hpp"
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/uintp.hpp b/contrib/python/pythran/pythran/pythonic/numpy/uintp.hpp
new file mode 100644
index 00000000000..41b9a149c98
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/uintp.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_NUMPY_UINTP_HPP
+#define PYTHONIC_NUMPY_UINTP_HPP
+
+#include "pythonic/include/numpy/uintp.hpp"
+
+#include "pythonic/types/numpy_op_helper.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/meta.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ inline uintptr_t uintp()
+ {
+ return uintptr_t();
+ }
+
+ template <class V>
+ uintptr_t uintp(V v)
+ {
+ return v;
+ }
+ } // namespace details
+
+#define NUMPY_NARY_FUNC_NAME uintp
+#define NUMPY_NARY_FUNC_SYM details::uintp
+#include "pythonic/types/numpy_nary_expr.hpp"
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ulonglong.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ulonglong.hpp
new file mode 100644
index 00000000000..4e536d97387
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ulonglong.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_NUMPY_ULONGLONG_HPP
+#define PYTHONIC_NUMPY_ULONGLONG_HPP
+
+#include "pythonic/include/numpy/ulonglong.hpp"
+
+#include "pythonic/types/numpy_op_helper.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/meta.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ inline unsigned long long ulonglong()
+ {
+ return {};
+ }
+
+ template <class V>
+ unsigned long long ulonglong(V v)
+ {
+ return v;
+ }
+ } // namespace details
+
+#define NUMPY_NARY_FUNC_NAME ulonglong
+#define NUMPY_NARY_FUNC_SYM details::ulonglong
+#include "pythonic/types/numpy_nary_expr.hpp"
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/union1d.hpp b/contrib/python/pythran/pythran/pythonic/numpy/union1d.hpp
new file mode 100644
index 00000000000..275d4d816bd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/union1d.hpp
@@ -0,0 +1,47 @@
+#ifndef PYTHONIC_NUMPY_UNION1D_HPP
+#define PYTHONIC_NUMPY_UNION1D_HPP
+
+#include "pythonic/include/numpy/union1d.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+
+#include <set>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace
+ {
+ template <class I, class O>
+ void _union1d(I begin, I end, O &out, utils::int_<1>)
+ {
+ for (; begin != end; ++begin)
+ out.insert(*begin);
+ }
+
+ template <class I, class O, size_t N>
+ void _union1d(I begin, I end, O &out, utils::int_<N>)
+ {
+ for (; begin != end; ++begin)
+ _union1d((*begin).begin(), (*begin).end(), out, utils::int_<N - 1>());
+ }
+ }
+
+ template <class E, class F>
+ types::ndarray<
+ typename __combined<typename E::dtype, typename F::dtype>::type,
+ types::pshape<long>>
+ union1d(E const &e, F const &f)
+ {
+ std::set<typename __combined<typename E::dtype, typename F::dtype>::type>
+ res;
+ _union1d(e.begin(), e.end(), res, utils::int_<E::value>());
+ _union1d(f.begin(), f.end(), res, utils::int_<F::value>());
+ return {res};
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/unique.hpp b/contrib/python/pythran/pythran/pythonic/numpy/unique.hpp
new file mode 100644
index 00000000000..822077f5fde
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/unique.hpp
@@ -0,0 +1,447 @@
+#ifndef PYTHONIC_NUMPY_UNIQUE_HPP
+#define PYTHONIC_NUMPY_UNIQUE_HPP
+
+#include "pythonic/include/numpy/unique.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/allocate.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <map>
+#include <set>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace
+ {
+ template <class I, class O>
+ void _unique1(I begin, I end, O &out, utils::int_<1>)
+ {
+ out.insert(begin, end);
+ }
+
+ template <class I, class O, size_t N>
+ void _unique1(I begin, I end, O &out, utils::int_<N>)
+ {
+ for (; begin != end; ++begin)
+ _unique1((*begin).begin(), (*begin).end(), out, utils::int_<N - 1>());
+ }
+
+ template <class I, class O0, class O1>
+ void _unique2(I begin, I end, O0 &out0, O1 &out1, long &i, utils::int_<1>)
+ {
+ for (; begin != end; ++begin, ++i) {
+ auto pair = out0.insert(*begin);
+ if (pair.second)
+ out1.push_back(i);
+ }
+ }
+
+ template <class I, class O0, class O1, size_t N>
+ void _unique2(I begin, I end, O0 &out0, O1 &out1, long &i, utils::int_<N>)
+ {
+ for (; begin != end; ++begin)
+ _unique2((*begin).begin(), (*begin).end(), out0, out1, i,
+ utils::int_<N - 1>());
+ }
+ template <class I, class O0, class O1, class O2>
+ void _unique3(I begin, I end, O0 &out0, O1 &out1, O2 &out2, long &i,
+ utils::int_<1>)
+ {
+ for (; begin != end; ++begin, ++i) {
+ auto pair = out0.insert(*begin);
+ out2[i] = std::distance(out0.begin(), pair.first);
+ if (pair.second)
+ out1.push_back(i);
+ }
+ }
+ template <class I, class O0, class O1, class O2, size_t N>
+ void _unique3(I begin, I end, O0 &out0, O1 &out1, O2 &out2, long &i,
+ utils::int_<N>)
+ {
+ for (; begin != end; ++begin)
+ _unique3((*begin).begin(), (*begin).end(), out0, out1, out2, i,
+ utils::int_<N - 1>());
+ }
+
+ template <class I, class O1, class O2, class O3>
+ void _unique4(I begin, I end, O1 &out1, O2 &out2, O3 &out3, long &i,
+ utils::int_<1>)
+ {
+ for (; begin != end; ++begin, ++i) {
+ auto res = out3.insert(std::make_pair(*begin, 0));
+ res.first->second += 1;
+ out2[i] = std::distance(out3.begin(), res.first);
+ if (res.second) {
+ out1.push_back(i);
+ }
+ }
+ }
+ template <class I, class O1, class O2, class O3, size_t N>
+ void _unique4(I begin, I end, O1 &out1, O2 &out2, O3 &out3, long &i,
+ utils::int_<N>)
+ {
+ for (; begin != end; ++begin)
+ _unique4((*begin).begin(), (*begin).end(), out1, out2, out3, i,
+ utils::int_<N - 1>());
+ }
+ template <class I, class O0, class O2>
+ void _unique5(I begin, I end, O0 &out0, O2 &out2, long &i, utils::int_<1>)
+ {
+ for (; begin != end; ++begin, ++i) {
+ auto pair = out0.insert(*begin);
+ out2[i] = std::distance(out0.begin(), pair.first);
+ }
+ }
+ template <class I, class O0, class O2, size_t N>
+ void _unique5(I begin, I end, O0 &out0, O2 &out2, long &i, utils::int_<N>)
+ {
+ for (; begin != end; ++begin)
+ _unique5((*begin).begin(), (*begin).end(), out0, out2, i,
+ utils::int_<N - 1>());
+ }
+
+ template <class I, class O1, class O3>
+ void _unique6(I begin, I end, O1 &out1, O3 &out3, long &i, utils::int_<1>)
+ {
+ for (; begin != end; ++begin, ++i) {
+ auto res = out3.insert(std::make_pair(*begin, 0));
+ res.first->second += 1;
+ if (res.second) {
+ out1.push_back(i);
+ }
+ }
+ }
+ template <class I, class O1, class O3, size_t N>
+ void _unique6(I begin, I end, O1 &out1, O3 &out3, long &i, utils::int_<N>)
+ {
+ for (; begin != end; ++begin)
+ _unique6((*begin).begin(), (*begin).end(), out1, out3, i,
+ utils::int_<N - 1>());
+ }
+
+ template <class I, class O2, class O3>
+ void _unique7(I begin, I end, O2 &out2, O3 &out3, long &i, utils::int_<1>)
+ {
+ for (; begin != end; ++begin, ++i) {
+ auto res = out3.insert(std::make_pair(*begin, 0));
+ res.first->second += 1;
+ out2[i] = std::distance(out3.begin(), res.first);
+ }
+ }
+ template <class I, class O2, class O3, size_t N>
+ void _unique7(I begin, I end, O2 &out2, O3 &out3, long &i, utils::int_<N>)
+ {
+ for (; begin != end; ++begin)
+ _unique7((*begin).begin(), (*begin).end(), out2, out3, i,
+ utils::int_<N - 1>());
+ }
+
+ template <class I, class O3>
+ void _unique8(I begin, I end, O3 &out3, long &i, utils::int_<1>)
+ {
+ for (; begin != end; ++begin, ++i) {
+ auto res = out3.insert(std::make_pair(*begin, 0));
+ res.first->second += 1;
+ }
+ }
+ template <class I, class O3, size_t N>
+ void _unique8(I begin, I end, O3 &out3, long &i, utils::int_<N>)
+ {
+ for (; begin != end; ++begin)
+ _unique8((*begin).begin(), (*begin).end(), out3, i,
+ utils::int_<N - 1>());
+ }
+ } // namespace
+
+ template <class E>
+ types::ndarray<typename E::dtype, types::pshape<long>> unique(E const &expr)
+ {
+ using dtype = typename E::dtype;
+ std::set<dtype, std::less<dtype>, utils::allocator<dtype>> res;
+ _unique1(expr.begin(), expr.end(), res, utils::int_<E::value>());
+ return {res};
+ }
+
+ template <class E>
+ std::tuple<types::ndarray<typename E::dtype, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>>
+ unique(E const &expr, types::true_immediate return_index)
+ {
+ using dtype = typename E::dtype;
+ std::set<dtype, std::less<dtype>, utils::allocator<dtype>> res;
+ std::vector<long, utils::allocator<long>> return_index_res;
+ long i = 0;
+ _unique2(expr.begin(), expr.end(), res, return_index_res, i,
+ utils::int_<E::value>());
+ return std::make_tuple(
+ types::ndarray<dtype, types::pshape<long>>(res),
+ types::ndarray<long, types::pshape<long>>(return_index_res));
+ }
+
+ template <class E>
+ types::ndarray<typename E::dtype, types::pshape<long>>
+ unique(E const &expr, types::false_immediate return_index)
+ {
+ using dtype = typename E::dtype;
+ std::set<dtype, std::less<dtype>, utils::allocator<dtype>> res;
+ _unique1(expr.begin(), expr.end(), res, utils::int_<E::value>());
+ return {res};
+ }
+
+ template <class E>
+ std::tuple<types::ndarray<typename E::dtype, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>>
+ unique(E const &expr, types::false_immediate return_index,
+ types::true_immediate return_inverse)
+ {
+ using dtype = typename E::dtype;
+ std::set<dtype, std::less<dtype>, utils::allocator<dtype>> res;
+ types::ndarray<long, types::pshape<long>> return_inverse_res(
+ types::pshape<long>{expr.flat_size()}, builtins::None);
+ long i = 0;
+ _unique5(expr.begin(), expr.end(), res, return_inverse_res, i,
+ utils::int_<E::value>());
+ return std::make_tuple(types::ndarray<dtype, types::pshape<long>>(res),
+ return_inverse_res);
+ }
+
+ template <class E>
+ types::ndarray<typename E::dtype, types::pshape<long>>
+ unique(E const &expr, types::false_immediate return_index,
+ types::false_immediate return_inverse)
+ {
+ using dtype = typename E::dtype;
+ std::set<dtype, std::less<dtype>, utils::allocator<dtype>> res;
+ _unique1(expr.begin(), expr.end(), res, utils::int_<E::value>());
+ return {res};
+ }
+
+ template <class E>
+ std::tuple<types::ndarray<typename E::dtype, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>>
+ unique(E const &expr, types::true_immediate return_index,
+ types::false_immediate return_inverse)
+ {
+ return unique(expr, return_index);
+ }
+
+ template <class E>
+ std::tuple<types::ndarray<typename E::dtype, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>>
+ unique(E const &expr, types::true_immediate return_index,
+ types::true_immediate return_inverse)
+ {
+ assert(return_inverse && "invalid signature otherwise");
+
+ using dtype = typename E::dtype;
+ std::set<dtype, std::less<dtype>, utils::allocator<dtype>> res;
+ std::vector<long, utils::allocator<long>> return_index_res;
+ types::ndarray<long, types::pshape<long>> return_inverse_res(
+ types::pshape<long>{expr.flat_size()}, builtins::None);
+ long i = 0;
+ _unique3(expr.begin(), expr.end(), res, return_index_res,
+ return_inverse_res, i, utils::int_<E::value>());
+ return std::make_tuple(
+ types::ndarray<dtype, types::pshape<long>>(res),
+ types::ndarray<long, types::pshape<long>>(return_index_res),
+ return_inverse_res);
+ }
+
+ template <class E>
+ std::tuple<types::ndarray<typename E::dtype, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>>
+ unique(E const &expr, types::true_immediate return_index,
+ types::true_immediate return_inverse,
+ types::true_immediate return_counts)
+ {
+ assert(return_counts && "invalid signature otherwise");
+
+ std::vector<long, utils::allocator<long>> return_index_res;
+ types::ndarray<long, types::pshape<long>> return_inverse_res(
+ types::pshape<long>{expr.flat_size()}, builtins::None);
+
+ std::map<typename E::dtype, long> return_counts_map;
+ {
+ long i = 0;
+ _unique4(expr.begin(), expr.end(), return_index_res, return_inverse_res,
+ return_counts_map, i, utils::int_<E::value>());
+ }
+
+ types::pshape<long> shp{(long)return_counts_map.size()};
+
+ types::ndarray<long, types::pshape<long>> unique_array(shp, builtins::None);
+ types::ndarray<long, types::pshape<long>> return_counts_array(
+ shp, builtins::None);
+
+ {
+ long i = 0;
+ for (auto it = return_counts_map.begin(); it != return_counts_map.end();
+ ++i, ++it) {
+ unique_array.fast(i) = it->first;
+ return_counts_array.fast(i) = it->second;
+ }
+ }
+
+ return std::make_tuple(
+ unique_array,
+ types::ndarray<long, types::pshape<long>>(return_index_res),
+ return_inverse_res, return_counts_array);
+ }
+
+ template <class E>
+ std::tuple<types::ndarray<typename E::dtype, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>>
+ unique(E const &expr, types::true_immediate return_index,
+ types::true_immediate return_inverse,
+ types::false_immediate return_counts)
+ {
+ return unique(expr, return_index, return_inverse);
+ }
+
+ template <class E>
+ std::tuple<types::ndarray<typename E::dtype, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>>
+ unique(E const &expr, types::true_immediate return_index,
+ types::false_immediate return_inverse,
+ types::false_immediate return_counts)
+ {
+ return unique(expr, return_index);
+ }
+
+ template <class E>
+ std::tuple<types::ndarray<typename E::dtype, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>>
+ unique(E const &expr, types::true_immediate return_index,
+ types::false_immediate return_inverse,
+ types::true_immediate return_counts)
+ {
+ std::vector<long, utils::allocator<long>> return_index_res;
+
+ std::map<typename E::dtype, long> return_counts_map;
+ {
+ long i = 0;
+ _unique6(expr.begin(), expr.end(), return_index_res, return_counts_map, i,
+ utils::int_<E::value>());
+ }
+
+ types::pshape<long> shp{(long)return_counts_map.size()};
+
+ types::ndarray<long, types::pshape<long>> unique_array(shp, builtins::None);
+ types::ndarray<long, types::pshape<long>> return_counts_array(
+ shp, builtins::None);
+
+ {
+ long i = 0;
+ for (auto it = return_counts_map.begin(); it != return_counts_map.end();
+ ++i, ++it) {
+ unique_array.fast(i) = it->first;
+ return_counts_array.fast(i) = it->second;
+ }
+ }
+
+ return std::make_tuple(
+ unique_array,
+ types::ndarray<long, types::pshape<long>>(return_index_res),
+ return_counts_array);
+ }
+
+ template <class E>
+ std::tuple<types::ndarray<typename E::dtype, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>>
+ unique(E const &expr, types::false_immediate return_index,
+ types::true_immediate return_inverse,
+ types::false_immediate return_counts)
+ {
+ return unique(expr, return_index, return_inverse);
+ }
+
+ template <class E>
+ std::tuple<types::ndarray<typename E::dtype, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>>
+ unique(E const &expr, types::false_immediate return_index,
+ types::true_immediate return_inverse,
+ types::true_immediate return_counts)
+ {
+ types::ndarray<long, types::pshape<long>> return_inverse_res(
+ types::pshape<long>{expr.flat_size()}, builtins::None);
+
+ std::map<typename E::dtype, long> return_counts_map;
+ {
+ long i = 0;
+ _unique7(expr.begin(), expr.end(), return_inverse_res, return_counts_map,
+ i, utils::int_<E::value>());
+ }
+
+ types::pshape<long> shp{(long)return_counts_map.size()};
+
+ types::ndarray<long, types::pshape<long>> unique_array(shp, builtins::None);
+ types::ndarray<long, types::pshape<long>> return_counts_array(
+ shp, builtins::None);
+
+ {
+ long i = 0;
+ for (auto it = return_counts_map.begin(); it != return_counts_map.end();
+ ++i, ++it) {
+ unique_array.fast(i) = it->first;
+ return_counts_array.fast(i) = it->second;
+ }
+ }
+
+ return std::make_tuple(unique_array, return_inverse_res,
+ return_counts_array);
+ }
+
+ template <class E>
+ types::ndarray<typename E::dtype, types::pshape<long>>
+ unique(E const &expr, types::false_immediate return_index,
+ types::false_immediate return_inverse,
+ types::false_immediate return_counts)
+ {
+ return unique(expr);
+ }
+
+ template <class E>
+ std::tuple<types::ndarray<typename E::dtype, types::pshape<long>>,
+ types::ndarray<long, types::pshape<long>>>
+ unique(E const &expr, types::false_immediate return_index,
+ types::false_immediate return_inverse,
+ types::true_immediate return_counts)
+ {
+ std::map<typename E::dtype, long> return_counts_map;
+ {
+ long i = 0;
+ _unique8(expr.begin(), expr.end(), return_counts_map, i,
+ utils::int_<E::value>());
+ }
+
+ types::pshape<long> shp{(long)return_counts_map.size()};
+
+ types::ndarray<long, types::pshape<long>> unique_array(shp, builtins::None);
+ types::ndarray<long, types::pshape<long>> return_counts_array(
+ shp, builtins::None);
+
+ {
+ long i = 0;
+ for (auto it = return_counts_map.begin(); it != return_counts_map.end();
+ ++i, ++it) {
+ unique_array.fast(i) = it->first;
+ return_counts_array.fast(i) = it->second;
+ }
+ }
+
+ return std::make_tuple(unique_array, return_counts_array);
+ }
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/unravel_index.hpp b/contrib/python/pythran/pythran/pythonic/numpy/unravel_index.hpp
new file mode 100644
index 00000000000..e72ef8e48ba
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/unravel_index.hpp
@@ -0,0 +1,45 @@
+#ifndef PYTHONIC_NUMPY_UNRAVEL_INDEX_HPP
+#define PYTHONIC_NUMPY_UNRAVEL_INDEX_HPP
+
+#include "pythonic/include/numpy/unravel_index.hpp"
+#include "pythonic/builtins/ValueError.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace
+ {
+ template <class E, class ShapeIt, class RetIt>
+ void _unravel_index(E expr, ShapeIt shape_it, ShapeIt end_it, RetIt ret_it)
+ {
+ while (shape_it != end_it) {
+ auto &v = *shape_it;
+ auto tmp = expr / v;
+ *ret_it = expr - v *tmp;
+ expr = tmp;
+ ++shape_it;
+ ++ret_it;
+ }
+ }
+ }
+
+ template <class E, class S>
+ typename std::enable_if<std::is_scalar<E>::value,
+ types::array<long, std::tuple_size<S>::value>>::type
+ unravel_index(E const &expr, S const &shape, types::str const &order)
+ {
+ types::array<long, std::tuple_size<S>::value> ret;
+ if (order[0] == "C") {
+ _unravel_index(expr, shape.rbegin(), shape.rend(), ret.rbegin());
+ } else if (order[0] == "F") {
+ _unravel_index(expr, shape.begin(), shape.end(), ret.begin());
+ } else {
+ throw types::ValueError("Invalid order");
+ }
+ return ret;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/unwrap.hpp b/contrib/python/pythran/pythran/pythonic/numpy/unwrap.hpp
new file mode 100644
index 00000000000..3eee2077372
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/unwrap.hpp
@@ -0,0 +1,59 @@
+#ifndef PYTHONIC_NUMPY_UNWRAP_HPP
+#define PYTHONIC_NUMPY_UNWRAP_HPP
+
+#include "pythonic/include/numpy/unwrap.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/int_.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/numpy/pi.hpp"
+
+#include <pythonic/numpy/maximum.hpp>
+#include <pythonic/numpy/abs.hpp>
+#include <pythonic/numpy/round.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace
+ {
+ template <class I0, class I1>
+ void _unwrap(I0 ibegin, I0 iend, I1 obegin, double discont, utils::int_<1>)
+ {
+ *obegin = *ibegin;
+ ++ibegin;
+ for (; ibegin != iend; ++ibegin, ++obegin) {
+ if (functor::abs{}(*obegin - *ibegin) > discont)
+ *(obegin + 1) =
+ *ibegin +
+ 2 * pi * functor::round{}((*obegin - *ibegin) / (2 * pi));
+ else
+ *(obegin + 1) = *ibegin;
+ }
+ }
+
+ template <class I0, class I1, size_t N>
+ void _unwrap(I0 ibegin, I0 iend, I1 obegin, double discont, utils::int_<N>)
+ {
+ for (; ibegin != iend; ++ibegin, ++obegin)
+ _unwrap((*ibegin).begin(), (*ibegin).end(), (*obegin).begin(), discont,
+ utils::int_<N - 1>());
+ }
+ }
+
+ template <class E>
+ types::ndarray<double, typename E::shape_t> unwrap(E const &expr,
+ double discont)
+ {
+ discont = functor::maximum{}(discont, pi);
+ types::ndarray<double, typename E::shape_t> out(sutils::getshape(expr),
+ builtins::None);
+ _unwrap(expr.begin(), expr.end(), out.begin(), discont,
+ utils::int_<E::value>());
+ return out;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/ushort.hpp b/contrib/python/pythran/pythran/pythonic/numpy/ushort.hpp
new file mode 100644
index 00000000000..d74c77907f8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/ushort.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_NUMPY_USHORT_HPP
+#define PYTHONIC_NUMPY_USHORT_HPP
+
+#include "pythonic/include/numpy/ushort.hpp"
+
+#include "pythonic/types/numpy_op_helper.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/meta.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ namespace details
+ {
+
+ inline unsigned short ushort()
+ {
+ return {};
+ }
+
+ template <class V>
+ unsigned short ushort(V v)
+ {
+ return v;
+ }
+ } // namespace details
+
+#define NUMPY_NARY_FUNC_NAME ushort
+#define NUMPY_NARY_FUNC_SYM details::ushort
+#include "pythonic/types/numpy_nary_expr.hpp"
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/var.hpp b/contrib/python/pythran/pythran/pythonic/numpy/var.hpp
new file mode 100644
index 00000000000..fcfba97ab34
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/var.hpp
@@ -0,0 +1,86 @@
+#ifndef PYTHONIC_NUMPY_VAR_HPP
+#define PYTHONIC_NUMPY_VAR_HPP
+
+#include "pythonic/include/numpy/var.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/builtins/ValueError.hpp"
+#include "pythonic/numpy/add.hpp"
+#include "pythonic/numpy/conjugate.hpp"
+#include "pythonic/numpy/subtract.hpp"
+#include "pythonic/numpy/mean.hpp"
+#include "pythonic/builtins/pythran/abssqr.hpp"
+#include "pythonic/numpy/sum.hpp"
+#include "pythonic/numpy/empty_like.hpp"
+
+#include <algorithm>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class E>
+ auto var(E const &expr, types::none_type axis, types::none_type dtype,
+ types::none_type out, long ddof)
+ -> decltype(var_type<E>(std::real(mean(expr))))
+ {
+ auto m = mean(expr);
+ auto t = pythonic::numpy::functor::subtract{}(expr, m);
+ return sum(builtins::pythran::functor::abssqr{}(t)) /
+ var_type<E>(expr.flat_size() - ddof);
+ }
+
+ namespace
+ {
+ // this is a workaround for the lack of efficient support for broadcasting
+ // in pythonic
+ template <class T, class E, class M>
+ void _enlarge_copy_minus(T &&t, E const &e, M const &m, long axis,
+ utils::int_<1>)
+ {
+ for (long i = 0, n = e.template shape<0>(), p = m.template shape<0>();
+ i < n;)
+ for (long j = 0; j < p; ++j, ++i)
+ t.fast(i) = e.fast(i) - m.fast(j);
+ }
+
+ template <class T, class E, class M, size_t N>
+ void _enlarge_copy_minus(T &&t, E const &e, M const &m, long axis,
+ utils::int_<N>)
+ {
+ for (long i = 0, n = e.template shape<0>(), p = m.template shape<0>();
+ i < n;)
+ for (long j = 0; j < p; ++j, ++i)
+ _enlarge_copy_minus(t.fast(i), e.fast(i), m.fast(j), axis,
+ utils::int_<N - 1>());
+ }
+ }
+
+ template <class E>
+ auto var(E const &expr, long axis, types::none_type dtype,
+ types::none_type out, long ddof) ->
+ typename assignable<decltype(var_type<E>() * mean(expr, axis))>::type
+ {
+ auto m = mean(expr, axis);
+ if (axis == 0) {
+ auto t = pythonic::numpy::functor::subtract{}(expr, m);
+ return sum(builtins::pythran::functor::abssqr{}(t), axis) /=
+ var_type<E>(expr.template shape<0>() - ddof);
+ } else {
+ types::array<long, E::value> shp = sutils::getshape(expr);
+ shp[axis] = 1;
+ auto mp = m.reshape(shp);
+
+ auto t = empty_like(expr);
+ _enlarge_copy_minus(t, expr, mp, axis, utils::int_<E::value>());
+ return sum(builtins::pythran::functor::abssqr{}(t), axis) /=
+ var_type<E>(sutils::getshape(expr)[axis] - ddof);
+ }
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/vdot.hpp b/contrib/python/pythran/pythran/pythonic/numpy/vdot.hpp
new file mode 100644
index 00000000000..575d6df38ec
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/vdot.hpp
@@ -0,0 +1,34 @@
+#ifndef PYTHONIC_NUMPY_VDOT_HPP
+#define PYTHONIC_NUMPY_VDOT_HPP
+
+#include "pythonic/include/numpy/vdot.hpp"
+
+#include "pythonic/numpy/asarray.hpp"
+#include "pythonic/numpy/conjugate.hpp"
+#include "pythonic/numpy/dot.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class U, class V>
+ auto vdot(U const &u, V const &v)
+ -> decltype(functor::dot{}(functor::asarray{}(u).flat(),
+ functor::asarray{}(v).flat()))
+ {
+ if (types::is_complex<typename U::dtype>::value &&
+ types::is_complex<typename V::dtype>::value) {
+ return functor::dot{}(functor::asarray{}(functor::conjugate{}(u)).flat(),
+ functor::asarray{}(v).flat());
+ } else {
+ return functor::dot{}(functor::asarray{}(u).flat(),
+ functor::asarray{}(v).flat());
+ }
+ }
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/vectorize.hpp b/contrib/python/pythran/pythran/pythonic/numpy/vectorize.hpp
new file mode 100644
index 00000000000..8452922d1da
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/vectorize.hpp
@@ -0,0 +1,41 @@
+#ifndef PYTHONIC_NUMPY_VECTORIZE_HPP
+#define PYTHONIC_NUMPY_VECTORIZE_HPP
+
+#include "pythonic/include/numpy/vectorize.hpp"
+#include "pythonic/types/numpy_expr.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ template <typename F>
+ template <typename... T>
+ auto vectorized<F>::operator()(T &&...args) const -> typename std::enable_if<
+ !types::valid_numexpr_parameters<typename std::decay<T>::type...>::value,
+ decltype(F{}(std::forward<T>(args)...))>::type
+ {
+ return F{}(std::forward<T>(args)...);
+ }
+
+ template <class F>
+ template <class... E>
+ typename std::enable_if<
+ types::valid_numexpr_parameters<typename std::decay<E>::type...>::value,
+ types::numpy_expr<F, typename types::adapt_type<E, E...>::type...>>::type
+ vectorized<F>::operator()(E &&...args) const
+ {
+ return {std::forward<E>(args)...};
+ }
+
+ template <class F>
+ vectorized<F> vectorize(F const &)
+ {
+ return {};
+ }
+
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/vstack.hpp b/contrib/python/pythran/pythran/pythonic/numpy/vstack.hpp
new file mode 100644
index 00000000000..ac933cead50
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/vstack.hpp
@@ -0,0 +1,35 @@
+#ifndef PYTHONIC_NUMPY_VSTACK_HPP
+#define PYTHONIC_NUMPY_VSTACK_HPP
+
+#include <pythonic/include/numpy/vstack.hpp>
+#include <pythonic/numpy/concatenate.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class ArraySequence>
+ auto vstack(ArraySequence &&seq) ->
+ typename std::enable_if<(impl::vstack_helper<ArraySequence>::value > 1),
+ impl::vstack_helper<ArraySequence>>::type
+ {
+
+ return concatenate(std::forward<ArraySequence>(seq), 0);
+ }
+
+ template <class ArraySequence>
+ auto vstack(ArraySequence &&seq) -> typename std::enable_if<
+ (impl::vstack_helper<ArraySequence>::value == 1),
+ decltype(std::declval<impl::vstack_helper<ArraySequence>>().reshape(
+ std::declval<types::array<long, 2>>()))>::type
+ {
+ auto &&temp = concatenate(std::forward<ArraySequence>(seq), 0);
+ long const seq_size = seq.size(), temp_size = temp.size();
+ types::array<long, 2> new_shape{{seq_size, temp_size / seq_size}};
+ return temp.reshape(new_shape);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/where.hpp b/contrib/python/pythran/pythran/pythonic/numpy/where.hpp
new file mode 100644
index 00000000000..fd5ee998025
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/where.hpp
@@ -0,0 +1,71 @@
+#ifndef PYTHONIC_NUMPY_WHERE_HPP
+#define PYTHONIC_NUMPY_WHERE_HPP
+
+#include "pythonic/include/numpy/where.hpp"
+
+#include "pythonic/numpy/asarray.hpp"
+#include "pythonic/numpy/nonzero.hpp"
+#include "pythonic/numpy/copy.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+ namespace impl
+ {
+ template <class E, class F, class G>
+ typename __combined<F, G>::type where(E const &cond, F const &true_,
+ G const &false_)
+ {
+ if (cond)
+ return true_;
+ else
+ return false_;
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME where
+#define NUMPY_NARY_FUNC_SYM impl::where
+#define NUMPY_NARY_RESHAPE_MODE reshape_type
+#include "pythonic/types/numpy_nary_expr.hpp"
+}
+
+namespace types
+{
+
+ template <>
+ struct Dereferencer<numpy::functor::where> {
+
+ template <class Ts>
+ auto operator()(Ts const &iters, utils::index_sequence<0, 1, 2>) ->
+ typename std::enable_if<
+ types::is_dtype<
+ typename std::remove_cv<typename std::remove_reference<
+ decltype(*std::get<0>(iters))>::type>::type>::value &&
+ types::is_dtype<
+ typename std::remove_cv<typename std::remove_reference<
+ decltype(*std::get<1>(iters))>::type>::type>::value &&
+ types::is_dtype<
+ typename std::remove_cv<typename std::remove_reference<
+ decltype(*std::get<2>(iters))>::type>::type>::value,
+ decltype(numpy::impl::where(*std::get<0>(iters),
+ *std::get<1>(iters),
+ *std::get<2>(iters)))>::type
+ {
+ if (*std::get<0>(iters))
+ return *std::get<1>(iters);
+ else
+ return *std::get<2>(iters);
+ }
+
+ template <class Ts, size_t... I>
+ auto operator()(Ts const &iters, utils::index_sequence<I...>, ...)
+ -> decltype(numpy::functor::where{}(*std::get<I>(iters)...))
+ {
+ return numpy::functor::where{}(*std::get<I>(iters)...);
+ }
+ };
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/zeros.hpp b/contrib/python/pythran/pythran/pythonic/numpy/zeros.hpp
new file mode 100644
index 00000000000..8879fdadd28
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/zeros.hpp
@@ -0,0 +1,49 @@
+#ifndef PYTHONIC_NUMPY_ZEROS_HPP
+#define PYTHONIC_NUMPY_ZEROS_HPP
+
+#include "pythonic/include/numpy/zeros.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/allocate.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class dtype>
+ typename dtype::type zeros(std::tuple<> const &shape, dtype d)
+ {
+ return static_cast<typename dtype::type>(0);
+ }
+
+ template <class pS, class dtype>
+ types::ndarray<typename dtype::type, sutils::shape_t<pS>>
+ zeros(pS const &shape, dtype d)
+ {
+ using T = typename dtype::type;
+ // use calloc even if we have a non integer type. This looks ok on modern
+ // architecture, although not really standard
+ auto *buffer = utils::callocate<T>(sutils::sprod(shape));
+ return {buffer, (sutils::shape_t<pS>)shape, types::ownership::owned};
+ }
+
+ template <class dtype>
+ types::ndarray<typename dtype::type, types::pshape<long>> zeros(long size,
+ dtype d)
+ {
+ return zeros(types::pshape<long>(size), d);
+ }
+
+ template <long N, class dtype>
+ types::ndarray<typename dtype::type,
+ types::pshape<std::integral_constant<long, N>>>
+ zeros(std::integral_constant<long, N>, dtype d)
+ {
+ return zeros(types::pshape<std::integral_constant<long, N>>({}), d);
+ }
+} // namespace numpy
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/numpy/zeros_like.hpp b/contrib/python/pythran/pythran/pythonic/numpy/zeros_like.hpp
new file mode 100644
index 00000000000..38024b1d159
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/numpy/zeros_like.hpp
@@ -0,0 +1,31 @@
+#ifndef PYTHONIC_NUMPY_ZEROSLIKE_HPP
+#define PYTHONIC_NUMPY_ZEROSLIKE_HPP
+
+#include "pythonic/include/numpy/zeros_like.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/numpy/zeros.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace numpy
+{
+
+ template <class E, class dtype>
+ auto zeros_like(E const &expr, dtype d)
+ -> decltype(zeros(sutils::getshape(expr), d))
+ {
+ return zeros(sutils::getshape(expr), d);
+ }
+
+ template <class E>
+ auto zeros_like(E const &expr, types::none_type)
+ -> decltype(zeros(sutils::getshape(expr),
+ types::dtype_t<typename E::dtype>()))
+ {
+ return zeros(sutils::getshape(expr), types::dtype_t<typename E::dtype>());
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/omp/get_num_threads.hpp b/contrib/python/pythran/pythran/pythonic/omp/get_num_threads.hpp
new file mode 100644
index 00000000000..73b81f0a9cc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/omp/get_num_threads.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_OMP_GET_NUM_THREADS_HPP
+#define PYTHONIC_OMP_GET_NUM_THREADS_HPP
+
+#include "pythonic/include/omp/get_num_threads.hpp"
+
+#include <omp.h>
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace omp
+{
+ long get_num_threads()
+ {
+ return omp_get_num_threads();
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/omp/get_thread_num.hpp b/contrib/python/pythran/pythran/pythonic/omp/get_thread_num.hpp
new file mode 100644
index 00000000000..652684eafef
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/omp/get_thread_num.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_OMP_GET_THREAD_NUM_HPP
+#define PYTHONIC_OMP_GET_THREAD_NUM_HPP
+
+#include "pythonic/include/omp/get_thread_num.hpp"
+
+#include <omp.h>
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace omp
+{
+
+ long get_thread_num()
+ {
+ return omp_get_thread_num();
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/omp/get_wtick.hpp b/contrib/python/pythran/pythran/pythonic/omp/get_wtick.hpp
new file mode 100644
index 00000000000..c31f1e25db3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/omp/get_wtick.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_OMP_GET_WTICK_HPP
+#define PYTHONIC_OMP_GET_WTICK_HPP
+
+#include "pythonic/include/omp/get_wtick.hpp"
+
+#include <omp.h>
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace omp
+{
+ long get_wtick()
+ {
+ return omp_get_wtick();
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/omp/get_wtime.hpp b/contrib/python/pythran/pythran/pythonic/omp/get_wtime.hpp
new file mode 100644
index 00000000000..c45c7de5f6b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/omp/get_wtime.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_OMP_GET_WTIME_HPP
+#define PYTHONIC_OMP_GET_WTIME_HPP
+
+#include "pythonic/include/omp/get_wtime.hpp"
+
+#include <omp.h>
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace omp
+{
+
+ long get_wtime()
+ {
+ return omp_get_wtime();
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/omp/in_parallel.hpp b/contrib/python/pythran/pythran/pythonic/omp/in_parallel.hpp
new file mode 100644
index 00000000000..80f053f5d61
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/omp/in_parallel.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_OMP_IN_PARALLEL_HPP
+#define PYTHONIC_OMP_IN_PARALLEL_HPP
+
+#include "pythonic/include/omp/in_parallel.hpp"
+
+#include <omp.h>
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace omp
+{
+
+ bool in_parallel()
+ {
+ return omp_in_parallel();
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/omp/set_nested.hpp b/contrib/python/pythran/pythran/pythonic/omp/set_nested.hpp
new file mode 100644
index 00000000000..3d5228de05d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/omp/set_nested.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_OMP_SET_NESTED_HPP
+#define PYTHONIC_OMP_SET_NESTED_HPP
+
+#include "pythonic/include/omp/set_nested.hpp"
+
+#include <omp.h>
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace omp
+{
+
+ void set_nested(long val)
+ {
+ return omp_set_nested(val);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/omp/set_num_threads.hpp b/contrib/python/pythran/pythran/pythonic/omp/set_num_threads.hpp
new file mode 100644
index 00000000000..305d88a1d34
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/omp/set_num_threads.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_OMP_SET_NUM_THREADS_HPP
+#define PYTHONIC_OMP_SET_NUM_THREADS_HPP
+
+#include "pythonic/include/omp/set_num_threads.hpp"
+
+#include <omp.h>
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace omp
+{
+ void set_num_threads(long num_threads)
+ {
+ return omp_set_num_threads(num_threads);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__abs__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__abs__.hpp
new file mode 100644
index 00000000000..a8c386ae6b6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__abs__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_ABS__HPP
+#define PYTHONIC_OPERATOR_ABS__HPP
+
+#include "pythonic/include/operator_/__abs__.hpp"
+#include "pythonic/builtins/abs.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__add__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__add__.hpp
new file mode 100644
index 00000000000..a43b04ad393
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__add__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_ADD__HPP
+#define PYTHONIC_OPERATOR_ADD__HPP
+
+#include "pythonic/include/operator_/__add__.hpp"
+#include "pythonic/operator_/add.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__and__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__and__.hpp
new file mode 100644
index 00000000000..25a5a9f353a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__and__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_AND__HPP
+#define PYTHONIC_OPERATOR_AND__HPP
+
+#include "pythonic/include/operator_/__and__.hpp"
+#include "pythonic/operator_/and_.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__concat__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__concat__.hpp
new file mode 100644
index 00000000000..3a840a60d48
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__concat__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_CONCAT__HPP
+#define PYTHONIC_OPERATOR_CONCAT__HPP
+
+#include "pythonic/include/operator_/__concat__.hpp"
+#include "pythonic/operator_/concat.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__contains__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__contains__.hpp
new file mode 100644
index 00000000000..b6f8187d5ae
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__contains__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_CONTAINS__HPP
+#define PYTHONIC_OPERATOR_CONTAINS__HPP
+
+#include "pythonic/include/operator_/__contains__.hpp"
+#include "pythonic/operator_/contains.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__delitem__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__delitem__.hpp
new file mode 100644
index 00000000000..5073d5f97b0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__delitem__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_DELITEM__HPP
+#define PYTHONIC_OPERATOR_DELITEM__HPP
+
+#include "pythonic/include/operator_/__delitem__.hpp"
+#include "pythonic/operator_/delitem.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__div__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__div__.hpp
new file mode 100644
index 00000000000..6a8a0cfc2c5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__div__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_DIV__HPP
+#define PYTHONIC_OPERATOR_DIV__HPP
+
+#include "pythonic/include/operator_/__div__.hpp"
+#include "pythonic/operator_/div.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__eq__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__eq__.hpp
new file mode 100644
index 00000000000..6852357e69d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__eq__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_EQ__HPP
+#define PYTHONIC_OPERATOR_EQ__HPP
+
+#include "pythonic/include/operator_/__eq__.hpp"
+#include "pythonic/operator_/eq.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__floordiv__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__floordiv__.hpp
new file mode 100644
index 00000000000..9170951bbf3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__floordiv__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_FLOORDIV__HPP
+#define PYTHONIC_OPERATOR_FLOORDIV__HPP
+
+#include "pythonic/include/operator_/__floordiv__.hpp"
+#include "pythonic/operator_/floordiv.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__ge__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__ge__.hpp
new file mode 100644
index 00000000000..e5b935bdb27
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__ge__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_GE__HPP
+#define PYTHONIC_OPERATOR_GE__HPP
+
+#include "pythonic/include/operator_/__ge__.hpp"
+#include "pythonic/operator_/ge.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__getitem__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__getitem__.hpp
new file mode 100644
index 00000000000..929b781b08f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__getitem__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_GETITEM__HPP
+#define PYTHONIC_OPERATOR_GETITEM__HPP
+
+#include "pythonic/include/operator_/__getitem__.hpp"
+#include "pythonic/operator_/getitem.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__gt__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__gt__.hpp
new file mode 100644
index 00000000000..3ca96d3194d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__gt__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_GT__HPP
+#define PYTHONIC_OPERATOR_GT__HPP
+
+#include "pythonic/include/operator_/__gt__.hpp"
+#include "pythonic/operator_/gt.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__iadd__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__iadd__.hpp
new file mode 100644
index 00000000000..e970920bd07
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__iadd__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_IADD__HPP
+#define PYTHONIC_OPERATOR_IADD__HPP
+
+#include "pythonic/include/operator_/__iadd__.hpp"
+#include "pythonic/operator_/iadd.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__iand__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__iand__.hpp
new file mode 100644
index 00000000000..62711c9a47e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__iand__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_IAND__HPP
+#define PYTHONIC_OPERATOR_IAND__HPP
+
+#include "pythonic/include/operator_/__iand__.hpp"
+#include "pythonic/operator_/iand.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__iconcat__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__iconcat__.hpp
new file mode 100644
index 00000000000..a76ad6f9ed4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__iconcat__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_ICONCAT__HPP
+#define PYTHONIC_OPERATOR_ICONCAT__HPP
+
+#include "pythonic/include/operator_/__iconcat__.hpp"
+#include "pythonic/operator_/iconcat.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__idiv__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__idiv__.hpp
new file mode 100644
index 00000000000..3bae8a698be
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__idiv__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_IDIV__HPP
+#define PYTHONIC_OPERATOR_IDIV__HPP
+
+#include "pythonic/include/operator_/__idiv__.hpp"
+#include "pythonic/operator_/idiv.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__ifloordiv__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__ifloordiv__.hpp
new file mode 100644
index 00000000000..ffd60234740
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__ifloordiv__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_IFLOORDIV__HPP
+#define PYTHONIC_OPERATOR_IFLOORDIV__HPP
+
+#include "pythonic/include/operator_/__ifloordiv__.hpp"
+#include "pythonic/operator_/ifloordiv.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__ilshift__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__ilshift__.hpp
new file mode 100644
index 00000000000..332d427dfda
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__ilshift__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_ILSHIFT__HPP
+#define PYTHONIC_OPERATOR_ILSHIFT__HPP
+
+#include "pythonic/include/operator_/__ilshift__.hpp"
+#include "pythonic/operator_/ilshift.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__imod__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__imod__.hpp
new file mode 100644
index 00000000000..0582a7b44c5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__imod__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_IMOD__HPP
+#define PYTHONIC_OPERATOR_IMOD__HPP
+
+#include "pythonic/include/operator_/__imod__.hpp"
+#include "pythonic/operator_/imod.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__imul__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__imul__.hpp
new file mode 100644
index 00000000000..02e4a64c248
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__imul__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_IMUL__HPP
+#define PYTHONIC_OPERATOR_IMUL__HPP
+
+#include "pythonic/include/operator_/__imul__.hpp"
+#include "pythonic/operator_/imul.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__inv__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__inv__.hpp
new file mode 100644
index 00000000000..3abf0beddfb
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__inv__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_INV__HPP
+#define PYTHONIC_OPERATOR_INV__HPP
+
+#include "pythonic/include/operator_/__inv__.hpp"
+#include "pythonic/operator_/invert.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__invert__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__invert__.hpp
new file mode 100644
index 00000000000..7ea90f3c28d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__invert__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_INVERT__HPP
+#define PYTHONIC_OPERATOR_INVERT__HPP
+
+#include "pythonic/include/operator_/__invert__.hpp"
+#include "pythonic/operator_/invert.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__ior__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__ior__.hpp
new file mode 100644
index 00000000000..ca93d3a23c6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__ior__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_IOR__HPP
+#define PYTHONIC_OPERATOR_IOR__HPP
+
+#include "pythonic/include/operator_/__ior__.hpp"
+#include "pythonic/operator_/ior.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__ipow__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__ipow__.hpp
new file mode 100644
index 00000000000..0f575fd47d5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__ipow__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_IPOW__HPP
+#define PYTHONIC_OPERATOR_IPOW__HPP
+
+#include "pythonic/include/operator_/__ipow__.hpp"
+#include "pythonic/operator_/ipow.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__irshift__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__irshift__.hpp
new file mode 100644
index 00000000000..3cef96663b3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__irshift__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_IRSHIFT__HPP
+#define PYTHONIC_OPERATOR_IRSHIFT__HPP
+
+#include "pythonic/include/operator_/__irshift__.hpp"
+#include "pythonic/operator_/irshift.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__isub__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__isub__.hpp
new file mode 100644
index 00000000000..5b07e050e74
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__isub__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_ISUB__HPP
+#define PYTHONIC_OPERATOR_ISUB__HPP
+
+#include "pythonic/include/operator_/__isub__.hpp"
+#include "pythonic/operator_/isub.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__itruediv__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__itruediv__.hpp
new file mode 100644
index 00000000000..129fa41a712
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__itruediv__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_ITRUEDIV__HPP
+#define PYTHONIC_OPERATOR_ITRUEDIV__HPP
+
+#include "pythonic/include/operator_/__itruediv__.hpp"
+#include "pythonic/operator_/itruediv.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__ixor__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__ixor__.hpp
new file mode 100644
index 00000000000..db1686bc740
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__ixor__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_IXOR__HPP
+#define PYTHONIC_OPERATOR_IXOR__HPP
+
+#include "pythonic/include/operator_/__ixor__.hpp"
+#include "pythonic/operator_/ixor.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__le__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__le__.hpp
new file mode 100644
index 00000000000..e8b65b009fd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__le__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_LE__HPP
+#define PYTHONIC_OPERATOR_LE__HPP
+
+#include "pythonic/include/operator_/__le__.hpp"
+#include "pythonic/operator_/le.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__lshift__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__lshift__.hpp
new file mode 100644
index 00000000000..34262c731e5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__lshift__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_LSHIFT__HPP
+#define PYTHONIC_OPERATOR_LSHIFT__HPP
+
+#include "pythonic/include/operator_/__lshift__.hpp"
+#include "pythonic/operator_/lshift.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__lt__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__lt__.hpp
new file mode 100644
index 00000000000..d6311036bc6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__lt__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_LT__HPP
+#define PYTHONIC_OPERATOR_LT__HPP
+
+#include "pythonic/include/operator_/__lt__.hpp"
+#include "pythonic/operator_/lt.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__matmul__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__matmul__.hpp
new file mode 100644
index 00000000000..d27875150fd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__matmul__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_MATMUL__HPP
+#define PYTHONIC_OPERATOR_MATMUL__HPP
+
+#include "pythonic/include/operator_/__matmul__.hpp"
+#include "pythonic/operator_/matmul.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__mod__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__mod__.hpp
new file mode 100644
index 00000000000..5025e594a1a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__mod__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_MOD__HPP
+#define PYTHONIC_OPERATOR_MOD__HPP
+
+#include "pythonic/include/operator_/__mod__.hpp"
+#include "pythonic/operator_/mod.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__mul__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__mul__.hpp
new file mode 100644
index 00000000000..f5bc00155fb
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__mul__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_MUL__HPP
+#define PYTHONIC_OPERATOR_MUL__HPP
+
+#include "pythonic/include/operator_/__mul__.hpp"
+#include "pythonic/operator_/mul.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__ne__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__ne__.hpp
new file mode 100644
index 00000000000..2f20245817d
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__ne__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_NE__HPP
+#define PYTHONIC_OPERATOR_NE__HPP
+
+#include "pythonic/include/operator_/__ne__.hpp"
+#include "pythonic/operator_/ne.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__neg__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__neg__.hpp
new file mode 100644
index 00000000000..a36e8666210
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__neg__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_NEG__HPP
+#define PYTHONIC_OPERATOR_NEG__HPP
+
+#include "pythonic/include/operator_/__neg__.hpp"
+#include "pythonic/operator_/neg.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__not__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__not__.hpp
new file mode 100644
index 00000000000..804f5e9c4b3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__not__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_NOT__HPP
+#define PYTHONIC_OPERATOR_NOT__HPP
+
+#include "pythonic/include/operator_/__not__.hpp"
+#include "pythonic/operator_/not_.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__or__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__or__.hpp
new file mode 100644
index 00000000000..1b7be82a9fc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__or__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_OR__HPP
+#define PYTHONIC_OPERATOR_OR__HPP
+
+#include "pythonic/include/operator_/__or__.hpp"
+#include "pythonic/operator_/or_.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__pos__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__pos__.hpp
new file mode 100644
index 00000000000..01abf9bf122
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__pos__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_POS__HPP
+#define PYTHONIC_OPERATOR_POS__HPP
+
+#include "pythonic/include/operator_/__pos__.hpp"
+#include "pythonic/operator_/pos.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__rshift__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__rshift__.hpp
new file mode 100644
index 00000000000..e278c3edd84
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__rshift__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_RSHIFT__HPP
+#define PYTHONIC_OPERATOR_RSHIFT__HPP
+
+#include "pythonic/include/operator_/__rshift__.hpp"
+#include "pythonic/operator_/rshift.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__sub__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__sub__.hpp
new file mode 100644
index 00000000000..c9d0b1c0191
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__sub__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_SUB__HPP
+#define PYTHONIC_OPERATOR_SUB__HPP
+
+#include "pythonic/include/operator_/__sub__.hpp"
+#include "pythonic/operator_/sub.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__truediv__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__truediv__.hpp
new file mode 100644
index 00000000000..3c2b4db743f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__truediv__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_TRUEDIV__HPP
+#define PYTHONIC_OPERATOR_TRUEDIV__HPP
+
+#include "pythonic/include/operator_/__truediv__.hpp"
+#include "pythonic/operator_/truediv.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/__xor__.hpp b/contrib/python/pythran/pythran/pythonic/operator_/__xor__.hpp
new file mode 100644
index 00000000000..0bc39c59af6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/__xor__.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_XOR__HPP
+#define PYTHONIC_OPERATOR_XOR__HPP
+
+#include "pythonic/include/operator_/__xor__.hpp"
+#include "pythonic//operator_/xor_.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/abs.hpp b/contrib/python/pythran/pythran/pythonic/operator_/abs.hpp
new file mode 100644
index 00000000000..47ee998c25a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/abs.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_ABS_HPP
+#define PYTHONIC_OPERATOR_ABS_HPP
+
+#include "pythonic/include/operator_/abs.hpp"
+#include "pythonic/builtins/abs.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/concat.hpp b/contrib/python/pythran/pythran/pythonic/operator_/concat.hpp
new file mode 100644
index 00000000000..17e8e817788
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/concat.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_OPERATOR_CONCAT_HPP
+#define PYTHONIC_OPERATOR_CONCAT_HPP
+
+#include "pythonic/include/operator_/concat.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ template <class A, class B>
+ auto concat(A &&a, B &&b) -> decltype(std::forward<A>(a) + std::forward<B>(b))
+ {
+ return std::forward<A>(a) + std::forward<B>(b);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/contains.hpp b/contrib/python/pythran/pythran/pythonic/operator_/contains.hpp
new file mode 100644
index 00000000000..9da329f31e3
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/contains.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_OPERATOR_CONTAINS_HPP
+#define PYTHONIC_OPERATOR_CONTAINS_HPP
+
+#include "pythonic/include/operator_/contains.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/builtins/in.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ template <class A, class B>
+ auto contains(A &&a, B &&b)
+ -> decltype(in(std::forward<A>(a), std::forward<B>(b)))
+ {
+ return in(std::forward<A>(a), std::forward<B>(b));
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/countOf.hpp b/contrib/python/pythran/pythran/pythonic/operator_/countOf.hpp
new file mode 100644
index 00000000000..a3f4203bd69
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/countOf.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_OPERATOR_COUNTOF_HPP
+#define PYTHONIC_OPERATOR_COUNTOF_HPP
+
+#include "pythonic/include/operator_/countOf.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <algorithm>
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ template <class A, class B>
+ long countOf(A &&a, B &&b)
+ {
+ return std::count(a.begin(), a.end(), std::forward<B>(b));
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/delitem.hpp b/contrib/python/pythran/pythran/pythonic/operator_/delitem.hpp
new file mode 100644
index 00000000000..0a44fa1c826
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/delitem.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_OPERATOR_DELITEM_HPP
+#define PYTHONIC_OPERATOR_DELITEM_HPP
+
+#include "pythonic/include/operator_/delitem.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/builtins/None.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ template <class A, class B>
+ types::none_type delitem(A &&a, B &&b)
+ {
+ std::forward<A>(a).remove(std::forward<B>(b));
+ return builtins::None;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/getitem.hpp b/contrib/python/pythran/pythran/pythonic/operator_/getitem.hpp
new file mode 100644
index 00000000000..1d5b21347e6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/getitem.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_OPERATOR_GETITEM_HPP
+#define PYTHONIC_OPERATOR_GETITEM_HPP
+
+#include "pythonic/include/operator_/getitem.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ template <class A, class B>
+ auto getitem(A &&a, B &&b) -> decltype(std::forward<A>(a)[std::forward<B>(b)])
+ {
+ return std::forward<A>(a)[std::forward<B>(b)];
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/iconcat.hpp b/contrib/python/pythran/pythran/pythonic/operator_/iconcat.hpp
new file mode 100644
index 00000000000..ea80f1ee60c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/iconcat.hpp
@@ -0,0 +1,41 @@
+#ifndef PYTHONIC_OPERATOR_ICONCAT_HPP
+#define PYTHONIC_OPERATOR_ICONCAT_HPP
+
+#include "pythonic/include/operator_/iconcat.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/list.hpp"
+#include "pythonic/types/set.hpp"
+#include "pythonic/types/dict.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ template <class A, class B>
+ A iconcat(A a, B const &b)
+ {
+ return a += b;
+ }
+
+ template <class A>
+ auto iconcat(types::empty_list a, types::list<A> b) -> decltype(b)
+ {
+ return b;
+ }
+
+ template <class K, class V>
+ auto iconcat(types::empty_dict a, types::dict<K, V> b) -> decltype(b)
+ {
+ return b;
+ }
+
+ template <class A>
+ auto iconcat(types::empty_set a, types::set<A> b) -> decltype(b)
+ {
+ return b;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/ifloordiv.hpp b/contrib/python/pythran/pythran/pythonic/operator_/ifloordiv.hpp
new file mode 100644
index 00000000000..d10087483e2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/ifloordiv.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_OPERATOR_IFLOORDIV_HPP
+#define PYTHONIC_OPERATOR_IFLOORDIV_HPP
+
+#include "pythonic/include/operator_/ifloordiv.hpp"
+#include "pythonic/operator_/mod.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ template <class A, class B>
+ A ifloordiv(A &&a, B &&b)
+ {
+ a -= mod(a, b);
+ a /= b;
+ return a;
+ }
+ template <class A, class B>
+ auto ifloordiv(A const &a, B const &b) -> decltype((a - mod(a, b)) / b)
+ {
+ return (a - mod(a, b)) / b;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/ilshift.hpp b/contrib/python/pythran/pythran/pythonic/operator_/ilshift.hpp
new file mode 100644
index 00000000000..b8f96c6b45b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/ilshift.hpp
@@ -0,0 +1,12 @@
+#ifndef PYTHONIC_OPERATOR_ILSHIFT_HPP
+#define PYTHONIC_OPERATOR_ILSHIFT_HPP
+
+#include "pythonic/include/operator_/ilshift.hpp"
+
+#define OPERATOR_NAME ilshift
+#define OPERATOR_SYMBOL <<
+#define OPERATOR_ISYMBOL <<=
+
+#include "pythonic/operator_/icommon.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/imatmul.hpp b/contrib/python/pythran/pythran/pythonic/operator_/imatmul.hpp
new file mode 100644
index 00000000000..5fbeb815329
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/imatmul.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHONIC_OPERATOR_IMATMUL_HPP
+#define PYTHONIC_OPERATOR_IMATMUL_HPP
+
+#include "pythonic/include/operator_/imatmul.hpp"
+
+#include "pythonic/numpy/dot.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ template <class A, class B>
+ A imatmul(A const &a, B &&b)
+ {
+ return numpy::functor::dot{}(a, std::forward<B>(b));
+ }
+
+ template <class A, class B>
+ A &imatmul(A &a, B &&b)
+ {
+ return a = numpy::functor::dot{}(a,
+ std::forward<B>(b)); // FIXME: improve that
+ }
+} // namespace operator_
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/imod.hpp b/contrib/python/pythran/pythran/pythonic/operator_/imod.hpp
new file mode 100644
index 00000000000..60378e768ea
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/imod.hpp
@@ -0,0 +1,26 @@
+#ifndef PYTHONIC_OPERATOR_IMOD_HPP
+#define PYTHONIC_OPERATOR_IMOD_HPP
+
+#include "pythonic/include/operator_/imod.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ template <class A, class B>
+ A imod(A const &a, B &&b)
+ {
+ return a % std::forward<B>(b);
+ }
+
+ template <class A, class B>
+ A &imod(A &a, B &&b)
+ {
+ return a %= std::forward<B>(b);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/indexOf.hpp b/contrib/python/pythran/pythran/pythonic/operator_/indexOf.hpp
new file mode 100644
index 00000000000..d007553e125
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/indexOf.hpp
@@ -0,0 +1,29 @@
+#ifndef PYTHONIC_OPERATOR_INDEXOF_HPP
+#define PYTHONIC_OPERATOR_INDEXOF_HPP
+
+#include "pythonic/include/operator_/indexOf.hpp"
+
+#include "pythonic/builtins/str.hpp"
+#include "pythonic/builtins/ValueError.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <algorithm>
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ template <class A, class B>
+ long indexOf(A &&a, B &&b)
+ {
+ auto where = std::find(a.begin(), a.end(), b);
+ if (where == a.end())
+ throw types::ValueError(builtins::anonymous::str(b) +
+ " is not in this sequence");
+ return where - a.begin();
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/inv.hpp b/contrib/python/pythran/pythran/pythonic/operator_/inv.hpp
new file mode 100644
index 00000000000..15dfef88bae
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/inv.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_OPERATOR_INV_HPP
+#define PYTHONIC_OPERATOR_INV_HPP
+
+#include "pythonic/include/operator_/inv.hpp"
+#include "pythonic/operator_/invert.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/invert.hpp b/contrib/python/pythran/pythran/pythonic/operator_/invert.hpp
new file mode 100644
index 00000000000..6985d3e36c0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/invert.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_OPERATOR_INVERT_HPP
+#define PYTHONIC_OPERATOR_INVERT_HPP
+
+#include "pythonic/include/operator_/invert.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ template <class A>
+ auto invert(A &&a) -> decltype(~std::forward<A>(a))
+ {
+ return ~std::forward<A>(a);
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/ipow.hpp b/contrib/python/pythran/pythran/pythonic/operator_/ipow.hpp
new file mode 100644
index 00000000000..0a69cf7b9e8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/ipow.hpp
@@ -0,0 +1,27 @@
+#ifndef PYTHONIC_OPERATOR_IPOW_HPP
+#define PYTHONIC_OPERATOR_IPOW_HPP
+
+#include "pythonic/include/operator_/ipow.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/builtins/pow.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ template <class A, class B>
+ A ipow(A const &a, B &&b)
+ {
+ return builtins::pow(a, std::forward<B>(b));
+ }
+ template <class A, class B>
+ A &ipow(A &a, B &&b)
+ {
+ return a = builtins::pow(a, std::forward<B>(b));
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/irshift.hpp b/contrib/python/pythran/pythran/pythonic/operator_/irshift.hpp
new file mode 100644
index 00000000000..f816c8f4788
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/irshift.hpp
@@ -0,0 +1,12 @@
+#ifndef PYTHONIC_OPERATOR_IRSHIFT_HPP
+#define PYTHONIC_OPERATOR_IRSHIFT_HPP
+
+#include "pythonic/include/operator_/irshift.hpp"
+
+#define OPERATOR_NAME irshift
+#define OPERATOR_SYMBOL >>
+#define OPERATOR_ISYMBOL >>=
+
+#include "pythonic/operator_/icommon.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/is_.hpp b/contrib/python/pythran/pythran/pythonic/operator_/is_.hpp
new file mode 100644
index 00000000000..f15fd01be0f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/is_.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_OPERATOR_IS_HPP
+#define PYTHONIC_OPERATOR_IS_HPP
+
+#include "pythonic/include/operator_/is_.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/builtins/id.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ template <class A, class B>
+ auto is_(A &&a, B &&b) -> decltype(builtins::id(std::forward<A>(a)) ==
+ builtins::id(std::forward<B>(b)))
+ {
+ return builtins::id(std::forward<A>(a)) == builtins::id(std::forward<B>(b));
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/is_not.hpp b/contrib/python/pythran/pythran/pythonic/operator_/is_not.hpp
new file mode 100644
index 00000000000..a2fbb1a98d5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/is_not.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_OPERATOR_ISNOT_HPP
+#define PYTHONIC_OPERATOR_ISNOT_HPP
+
+#include "pythonic/include/operator_/is_not.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ template <class A, class B>
+ auto is_not(A &&a, B &&b) -> decltype(builtins::id(std::forward<A>(a)) !=
+ builtins::id(std::forward<B>(b)))
+ {
+ return builtins::id(std::forward<A>(a)) != builtins::id(std::forward<B>(b));
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/itemgetter.hpp b/contrib/python/pythran/pythran/pythonic/operator_/itemgetter.hpp
new file mode 100644
index 00000000000..7d3bf6a0cbe
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/itemgetter.hpp
@@ -0,0 +1,80 @@
+#ifndef PYTHONIC_OPERATOR_ITEMGETTER_HPP
+#define PYTHONIC_OPERATOR_ITEMGETTER_HPP
+
+#include "pythonic/include/operator_/itemgetter.hpp"
+
+#include "pythonic/types/tuple.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/int_.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ inline itemgetter_return::itemgetter_return(long const &item) : i(item)
+ {
+ }
+
+ template <class A>
+ auto itemgetter_return::operator()(A const &a) const -> decltype(a[i])
+ {
+ return a[i];
+ }
+
+ inline itemgetter_return itemgetter(long item)
+ {
+ return itemgetter_return(item);
+ }
+
+ template <typename... Types>
+ itemgetter_tuple_return<Types...>::itemgetter_tuple_return(Types... items)
+ : items(items...)
+ {
+ }
+
+ template <typename... Types>
+ itemgetter_tuple_return<Types...>::itemgetter_tuple_return()
+ {
+ }
+
+ template <typename... Types>
+ template <class T, class A, size_t I>
+ void itemgetter_tuple_return<Types...>::helper(T &t, A const &a,
+ utils::int_<I>) const
+ {
+ std::get<I>(t) = a[std::get<I>(items)];
+ helper(t, a, utils::int_<I - 1>());
+ }
+
+ template <typename... Types>
+ template <class T, class A>
+ void itemgetter_tuple_return<Types...>::helper(T &t, A const &a,
+ utils::int_<0>) const
+ {
+ std::get<0>(t) = a[std::get<0>(items)];
+ }
+
+ template <typename... Types>
+ template <class A>
+ auto itemgetter_tuple_return<Types...>::operator()(A const &a) const
+ -> std::tuple<typename std::remove_cv<typename std::remove_reference<
+ decltype(a[std::declval<Types>()])>::type>::type...>
+ {
+ std::tuple<typename std::remove_cv<typename std::remove_reference<
+ decltype(a[std::declval<Types>()])>::type>::type...>
+ t;
+ helper(t, a, utils::int_<sizeof...(Types) - 1>());
+ return t;
+ }
+
+ template <class... L>
+ itemgetter_tuple_return<long, long, L...>
+ itemgetter(long const &item1, long const &item2, L... items)
+ {
+ return {item1, item2, items...};
+ }
+} // namespace operator_
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/itruediv.hpp b/contrib/python/pythran/pythran/pythonic/operator_/itruediv.hpp
new file mode 100644
index 00000000000..a52ac09eddd
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/itruediv.hpp
@@ -0,0 +1,35 @@
+#ifndef PYTHONIC_OPERATOR_ITRUEDIV_HPP
+#define PYTHONIC_OPERATOR_ITRUEDIV_HPP
+
+#include "pythonic/include/operator_/itruediv.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/operator_/truediv.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ template <class A, class B>
+ auto itruediv(A const &a, B &&b) -> decltype(truediv(a, std::forward<B>(b)))
+ {
+ return truediv(a, std::forward<B>(b));
+ }
+ template <class A, class B>
+ auto itruediv(A &a, B &&b) -> typename std::enable_if<
+ std::is_same<A, decltype(truediv(a, std::forward<B>(b)))>::value,
+ A &>::type
+ {
+ return a = truediv(a, std::forward<B>(b));
+ }
+ template <class A, class B>
+ auto itruediv(A &a, B &&b) -> typename std::enable_if<
+ !std::is_same<A, decltype(truediv(a, std::forward<B>(b)))>::value,
+ decltype(truediv(a, std::forward<B>(b)))>::type
+ {
+ return truediv(a, std::forward<B>(b));
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/matmul.hpp b/contrib/python/pythran/pythran/pythonic/operator_/matmul.hpp
new file mode 100644
index 00000000000..3a0ed65f720
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/matmul.hpp
@@ -0,0 +1,23 @@
+#ifndef PYTHONIC_OPERATOR_MATMUL_HPP
+#define PYTHONIC_OPERATOR_MATMUL_HPP
+
+#include "pythonic/include/operator_/matmul.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/numpy/dot.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+
+ template <class A, class B>
+ auto matmul(A &&a, B &&b)
+ -> decltype(numpy::functor::dot{}(std::forward<A>(a), std::forward<B>(b)))
+ {
+ return numpy::functor::dot{}(std::forward<A>(a), std::forward<B>(b));
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/truediv.hpp b/contrib/python/pythran/pythran/pythonic/operator_/truediv.hpp
new file mode 100644
index 00000000000..e9e5c144fe0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/truediv.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_OPERATOR_TRUEDIV_HPP
+#define PYTHONIC_OPERATOR_TRUEDIV_HPP
+
+#include "pythonic/include/operator_/truediv.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ template <class A, class B>
+ auto truediv(A &&a, B &&b)
+ -> decltype(std::forward<A>(a) / (double)std::forward<B>(b))
+ {
+ return std::forward<A>(a) / ((double)std::forward<B>(b));
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/operator_/truth.hpp b/contrib/python/pythran/pythran/pythonic/operator_/truth.hpp
new file mode 100644
index 00000000000..db623064bc8
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/operator_/truth.hpp
@@ -0,0 +1,19 @@
+#ifndef PYTHONIC_OPERATOR_TRUTH_HPP
+#define PYTHONIC_OPERATOR_TRUTH_HPP
+
+#include "pythonic/include/operator_/truth.hpp"
+
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace operator_
+{
+ inline bool truth(bool const &a)
+ {
+ return a;
+ }
+} // namespace operator_
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/os/path/join.hpp b/contrib/python/pythran/pythran/pythonic/os/path/join.hpp
new file mode 100644
index 00000000000..4f405268743
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/os/path/join.hpp
@@ -0,0 +1,71 @@
+#ifndef PYTHONIC_OS_PATH_JOIN_HPP
+#define PYTHONIC_OS_PATH_JOIN_HPP
+
+#ifdef WIN32
+#define OS_SEP '\\'
+#else
+#define OS_SEP '/'
+#endif
+
+#include "pythonic/include/os/path/join.hpp"
+
+#include "pythonic/types/str.hpp"
+
+PYTHONIC_NS_BEGIN
+namespace os
+{
+ namespace path
+ {
+ namespace
+ {
+ template <class T>
+ size_t sizeof_string(T const &s)
+ {
+ return s.size();
+ }
+
+ template <class T, class... Types>
+ size_t sizeof_string(T const &s, Types &&...tail)
+ {
+ return s.size() + sizeof_string(std::forward<Types>(tail)...);
+ }
+
+ inline void _join(types::str &buffer)
+ {
+ }
+
+ template <class T, class... Types>
+ void _join(types::str &buffer, T &&head, Types &&...tail)
+ {
+ if (((types::str)head)[0] == "/")
+ buffer = std::forward<T>(head);
+ else if (!buffer || *buffer.chars().rbegin() == OS_SEP ||
+ *buffer.rbegin() == "/")
+ buffer += std::forward<T>(head);
+ else {
+ buffer.chars() += OS_SEP;
+ buffer += std::forward<T>(head);
+ }
+ _join(buffer, std::forward<Types>(tail)...);
+ }
+ } // namespace
+
+ template <class T>
+ T join(T &&head)
+ {
+ return head;
+ }
+
+ template <class T, class... Types>
+ types::str join(T &&head, Types &&...tail)
+ {
+ types::str p = head;
+ p.reserve(sizeof_string(tail...));
+ _join(p, std::forward<Types>(tail)...);
+ return p;
+ }
+ } // namespace path
+} // namespace os
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/random/choice.hpp b/contrib/python/pythran/pythran/pythonic/random/choice.hpp
new file mode 100644
index 00000000000..ca0e3299ed5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/random/choice.hpp
@@ -0,0 +1,49 @@
+#ifndef PYTHONIC_RANDOM_CHOICE_HPP
+#define PYTHONIC_RANDOM_CHOICE_HPP
+
+#include "pythonic/include/random/choice.hpp"
+
+#include "pythonic/random/random.hpp"
+#include "pythonic/types/traits.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace random
+{
+
+ namespace details
+ {
+
+ template <class Seq>
+ typename std::enable_if<types::has_size<Seq>::value,
+ typename Seq::value_type>::type
+ choice(Seq const &seq)
+ {
+ auto tmp = seq.begin();
+ // std::advance not usable because it requires operator--
+ for (long n = random() * seq.size(); n; --n)
+ ++tmp;
+ return *tmp;
+ }
+
+ template <class Seq>
+ typename std::enable_if<!types::has_size<Seq>::value,
+ typename Seq::value_type>::type
+ choice(Seq const &seq)
+ {
+ using dtype = typename std::decay<typename Seq::value_type>::type;
+ std::vector<dtype, utils::allocator<dtype>> tmp(seq.begin(), seq.end());
+ return tmp[long(random() * tmp.size())];
+ }
+ } // namespace details
+
+ template <class Seq>
+ typename Seq::value_type choice(Seq const &seq)
+ {
+ return details::choice(seq);
+ }
+} // namespace random
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/random/expovariate.hpp b/contrib/python/pythran/pythran/pythonic/random/expovariate.hpp
new file mode 100644
index 00000000000..22f763aa3c7
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/random/expovariate.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_RANDOM_EXPOVARIATE_HPP
+#define PYTHONIC_RANDOM_EXPOVARIATE_HPP
+
+#include "pythonic/include/random/expovariate.hpp"
+
+#include "pythonic/random/random.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace random
+{
+ inline double expovariate(double l)
+ {
+ return std::exponential_distribution<>(l)(__random_generator);
+ }
+} // namespace random
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/random/gauss.hpp b/contrib/python/pythran/pythran/pythonic/random/gauss.hpp
new file mode 100644
index 00000000000..e0d77bac59f
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/random/gauss.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_RANDOM_GAUSS_HPP
+#define PYTHONIC_RANDOM_GAUSS_HPP
+
+#include "pythonic/include/random/gauss.hpp"
+
+#include "pythonic/random/random.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace random
+{
+
+ inline double gauss(double mu, double sigma)
+ {
+ return std::normal_distribution<>(mu, sigma)(__random_generator);
+ }
+} // namespace random
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/random/randint.hpp b/contrib/python/pythran/pythran/pythonic/random/randint.hpp
new file mode 100644
index 00000000000..5b44f597a85
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/random/randint.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_RANDOM_RANDINT_HPP
+#define PYTHONIC_RANDOM_RANDINT_HPP
+
+#include "pythonic/include/random/randint.hpp"
+
+#include "pythonic/random/randrange.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace random
+{
+
+ inline long randint(long a, long b)
+ {
+ // TODO: It should be implemented with an uniform_int_distribution
+ return randrange(a, b + 1);
+ }
+} // namespace random
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/random/random.hpp b/contrib/python/pythran/pythran/pythonic/random/random.hpp
new file mode 100644
index 00000000000..71b089d36cf
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/random/random.hpp
@@ -0,0 +1,21 @@
+#ifndef PYTHONIC_RANDOM_RANDOM_HPP
+#define PYTHONIC_RANDOM_RANDOM_HPP
+
+#include "pythonic/include/random/random.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include <random>
+
+PYTHONIC_NS_BEGIN
+
+namespace random
+{
+ inline double random()
+ {
+ static std::uniform_real_distribution<> uniform_distrib(0.0, 1.0);
+ return uniform_distrib(__random_generator);
+ }
+} // namespace random
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/random/randrange.hpp b/contrib/python/pythran/pythran/pythonic/random/randrange.hpp
new file mode 100644
index 00000000000..bb07f09d55c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/random/randrange.hpp
@@ -0,0 +1,32 @@
+#ifndef PYTHONIC_RANDOM_RANDRANGE_HPP
+#define PYTHONIC_RANDOM_RANDRANGE_HPP
+
+#include "pythonic/include/random/randrange.hpp"
+
+#include "pythonic/random/random.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <cmath>
+
+PYTHONIC_NS_BEGIN
+
+namespace random
+{
+ inline long randrange(long stop)
+ {
+ return long(random() * stop);
+ }
+
+ inline long randrange(long start, long stop)
+ {
+ return start + long(random() * (stop - start));
+ }
+
+ inline long randrange(long start, long stop, long step)
+ {
+ return start + step * long((random() * (stop - start)) / std::abs(step));
+ }
+} // namespace random
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/random/sample.hpp b/contrib/python/pythran/pythran/pythonic/random/sample.hpp
new file mode 100644
index 00000000000..59389af38c2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/random/sample.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_RANDOM_SAMPLE_HPP
+#define PYTHONIC_RANDOM_SAMPLE_HPP
+
+#include "pythonic/include/random/sample.hpp"
+
+#include "pythonic/random/random.hpp"
+#include "pythonic/utils/allocate.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include "pythonic/types/list.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace random
+{
+ template <class Iterable>
+ types::list<typename std::iterator_traits<
+ typename std::remove_cv<typename std::remove_reference<Iterable>::type>::
+ type::iterator>::value_type>
+ sample(Iterable &&s, size_t k)
+ {
+ using value_type = typename std::iterator_traits<typename std::remove_cv<
+ typename std::remove_reference<Iterable>::type>::type::iterator>::
+ value_type;
+ types::list<value_type> tmp(s.begin(), s.end());
+ std::vector<size_t, utils::allocator<size_t>> indices(tmp.size());
+ std::iota(indices.begin(), indices.end(), 0);
+ std::random_shuffle(indices.begin(), indices.end());
+ types::list<value_type> out(k);
+ for (size_t i = 0; i < k; i++)
+ out[i] = tmp[indices[i]];
+ return out;
+ }
+} // namespace random
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/random/seed.hpp b/contrib/python/pythran/pythran/pythonic/random/seed.hpp
new file mode 100644
index 00000000000..600ba0df8dc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/random/seed.hpp
@@ -0,0 +1,30 @@
+#ifndef PYTHONIC_RANDOM_SEED_HPP
+#define PYTHONIC_RANDOM_SEED_HPP
+
+#include "pythonic/include/random/seed.hpp"
+
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/random/random.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <ctime>
+
+PYTHONIC_NS_BEGIN
+
+namespace random
+{
+ inline types::none_type seed(long s)
+ {
+ __random_generator.seed(s);
+ return builtins::None;
+ }
+
+ inline types::none_type seed()
+ {
+ __random_generator.seed(time(nullptr));
+ return builtins::None;
+ }
+} // namespace random
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/random/shuffle.hpp b/contrib/python/pythran/pythran/pythonic/random/shuffle.hpp
new file mode 100644
index 00000000000..19b74344fdc
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/random/shuffle.hpp
@@ -0,0 +1,63 @@
+#ifndef PYTHONIC_RANDOM_SHUFFLE_HPP
+#define PYTHONIC_RANDOM_SHUFFLE_HPP
+
+#include "pythonic/include/random/shuffle.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/builtins/None.hpp"
+#include "pythonic/random/random.hpp"
+
+#include <limits>
+
+PYTHONIC_NS_BEGIN
+
+namespace random
+{
+
+ template <class T>
+ types::none_type shuffle(T &seq)
+ {
+ std::shuffle(seq.begin(), seq.end(), __random_generator);
+ return builtins::None;
+ }
+
+ namespace details
+ {
+ template <class function>
+ struct URG {
+ URG(function &&f) : randf(f)
+ {
+ }
+
+ typedef unsigned result_type;
+ static constexpr result_type min()
+ {
+ return 0;
+ }
+ /* -1 because of the floor() operation performed by the float->unsigned
+ * conversion */
+ static constexpr result_type max()
+ {
+ return std::numeric_limits<result_type>::max() - 1;
+ }
+ result_type operator()()
+ {
+ return randf() * std::numeric_limits<result_type>::max();
+ }
+
+ function randf;
+ };
+ }
+
+ template <class T, class function>
+ types::none_type shuffle(T &seq, function &&randf)
+ {
+ std::shuffle(seq.begin(), seq.end(),
+ details::URG<function>(std::forward<function>(randf)));
+ return builtins::None;
+ }
+}
+
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/random/uniform.hpp b/contrib/python/pythran/pythran/pythonic/random/uniform.hpp
new file mode 100644
index 00000000000..7556dc8a54c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/random/uniform.hpp
@@ -0,0 +1,20 @@
+#ifndef PYTHONIC_RANDOM_UNIFORM_HPP
+#define PYTHONIC_RANDOM_UNIFORM_HPP
+
+#include "pythonic/include/random/uniform.hpp"
+
+#include "pythonic/random/random.hpp"
+#include "pythonic/utils/functor.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace random
+{
+ inline double uniform(double a, double b)
+ {
+ return a + (b - a) * random();
+ }
+} // namespace random
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/scipy/special/binom.hpp b/contrib/python/pythran/pythran/pythonic/scipy/special/binom.hpp
new file mode 100644
index 00000000000..47204a73996
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/scipy/special/binom.hpp
@@ -0,0 +1,40 @@
+#ifndef PYTHONIC_SCIPY_SPECIAL_BINOM_HPP
+#define PYTHONIC_SCIPY_SPECIAL_BINOM_HPP
+
+#include "pythonic/include/scipy/special/binom.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+#include "pythonic/utils/boost_local_config.hpp"
+#include <boost/math/special_functions/binomial.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+ namespace details
+ {
+ template <class T0, class T1>
+ double binom(T0 n, T1 k)
+ {
+ static_assert(std::is_integral<T0>::value &&
+ std::is_integral<T1>::value,
+ "only support integer case of scipy.special.binom");
+ using namespace boost::math::policies;
+ return boost::math::binomial_coefficient<double>(
+ n, k, make_policy(promote_double<true>()));
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME binom
+#define NUMPY_NARY_FUNC_SYM details::binom
+#include "pythonic/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/scipy/special/chbevl.hpp b/contrib/python/pythran/pythran/pythonic/scipy/special/chbevl.hpp
new file mode 100644
index 00000000000..2e3b5b68f90
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/scipy/special/chbevl.hpp
@@ -0,0 +1,38 @@
+
+/* Adapated from Cephes Math Library Release 2.0: April, 1987
+ * Copyright 1985, 1987 by Stephen L. Moshier
+ * Direct inquiries to 30 Frost Street, Cambridge, MA 02140
+ */
+
+#ifndef PYTHONIC_SCIPY_SPECIAL_CHBEVL_HPP
+#define PYTHONIC_SCIPY_SPECIAL_CHBEVL_HPP
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+ template <size_t N>
+ double chbevl(double x, const double(&array)[N])
+ {
+ const double *p = &array[0];
+ double b0 = *p++;
+ double b1 = 0.0;
+ double b2;
+ size_t i = N - 1;
+
+ do {
+ b2 = b1;
+ b1 = b0;
+ b0 = x * b1 - b2 + *p++;
+ } while (--i);
+
+ return (0.5 * (b0 - b2));
+ }
+
+ } // namespace special
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/scipy/special/gamma.hpp b/contrib/python/pythran/pythran/pythonic/scipy/special/gamma.hpp
new file mode 100644
index 00000000000..2ee3b2b96de
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/scipy/special/gamma.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_SCIPY_SPECIAL_GAMMA_HPP
+#define PYTHONIC_SCIPY_SPECIAL_GAMMA_HPP
+
+#include "pythonic/include/scipy/special/gamma.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+
+#define NUMPY_NARY_FUNC_NAME gamma
+#define NUMPY_NARY_FUNC_SYM xsimd::tgamma
+#include "pythonic/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/scipy/special/gammaincinv.hpp b/contrib/python/pythran/pythran/pythonic/scipy/special/gammaincinv.hpp
new file mode 100644
index 00000000000..63eb790b05e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/scipy/special/gammaincinv.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_SCIPY_SPECIAL_GAMMAINCINV_HPP
+#define PYTHONIC_SCIPY_SPECIAL_GAMMAINCINV_HPP
+
+#include "pythonic/include/scipy/special/gammaincinv.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+#include "pythonic/utils/boost_local_config.hpp"
+#include <boost/math/special_functions/gamma.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+ namespace details
+ {
+ template <class T0, class T1>
+ double gammaincinv(T0 a, T1 p)
+ {
+ using namespace boost::math::policies;
+ return boost::math::gamma_p_inv(a, p,
+ make_policy(promote_double<true>()));
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME gammaincinv
+#define NUMPY_NARY_FUNC_SYM details::gammaincinv
+#include "pythonic/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/scipy/special/gammaln.hpp b/contrib/python/pythran/pythran/pythonic/scipy/special/gammaln.hpp
new file mode 100644
index 00000000000..82ad0f65532
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/scipy/special/gammaln.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_SCIPY_SPECIAL_GAMMALN_HPP
+#define PYTHONIC_SCIPY_SPECIAL_GAMMALN_HPP
+
+#include "pythonic/include/scipy/special/gammaln.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+
+#define NUMPY_NARY_FUNC_NAME gammaln
+#define NUMPY_NARY_FUNC_SYM xsimd::lgamma
+#include "pythonic/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/scipy/special/hankel1.hpp b/contrib/python/pythran/pythran/pythonic/scipy/special/hankel1.hpp
new file mode 100644
index 00000000000..0f20cd37b71
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/scipy/special/hankel1.hpp
@@ -0,0 +1,36 @@
+#ifndef PYTHONIC_SCIPY_SPECIAL_HANKEL1_HPP
+#define PYTHONIC_SCIPY_SPECIAL_HANKEL1_HPP
+
+#include "pythonic/include/scipy/special/hankel1.hpp"
+
+#include "pythonic/types/complex.hpp"
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+#include "pythonic/utils/boost_local_config.hpp"
+#include <boost/math/special_functions/hankel.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+ namespace details
+ {
+ template <class T0, class T1>
+ std::complex<double> hankel1(T0 x, T1 y)
+ {
+ return boost::math::cyl_hankel_1(x, y);
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME hankel1
+#define NUMPY_NARY_FUNC_SYM details::hankel1
+#include "pythonic/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/scipy/special/hankel2.hpp b/contrib/python/pythran/pythran/pythonic/scipy/special/hankel2.hpp
new file mode 100644
index 00000000000..ddce9a019d6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/scipy/special/hankel2.hpp
@@ -0,0 +1,36 @@
+#ifndef PYTHONIC_SCIPY_SPECIAL_HANKEL2_HPP
+#define PYTHONIC_SCIPY_SPECIAL_HANKEL2_HPP
+
+#include "pythonic/include/scipy/special/hankel2.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/types/complex.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+#include "pythonic/utils/boost_local_config.hpp"
+#include <boost/math/special_functions/hankel.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+ namespace details
+ {
+ template <class T0, class T1>
+ std::complex<double> hankel2(T0 x, T1 y)
+ {
+ return boost::math::cyl_hankel_2(x, y);
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME hankel2
+#define NUMPY_NARY_FUNC_SYM details::hankel2
+#include "pythonic/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/scipy/special/i0.hpp b/contrib/python/pythran/pythran/pythonic/scipy/special/i0.hpp
new file mode 100644
index 00000000000..e32de34b682
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/scipy/special/i0.hpp
@@ -0,0 +1,43 @@
+#ifndef PYTHONIC_SCIPY_SPECIAL_I0_HPP
+#define PYTHONIC_SCIPY_SPECIAL_I0_HPP
+
+#include "pythonic/include/scipy/special/i0.hpp"
+#include "pythonic/scipy/special/chbevl.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+ namespace details
+ {
+ template <class T>
+ double i0(T x_)
+ {
+ double y;
+ double x = x_;
+
+ if (x < 0)
+ x = -x;
+ if (x <= 8.0) {
+ y = (x / 2.0) - 2.0;
+ return (exp(x) * chbevl(y, A));
+ }
+
+ return (exp(x) * chbevl(32.0 / x - 2.0, B) / sqrt(x));
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME i0
+#define NUMPY_NARY_FUNC_SYM details::i0
+#include "pythonic/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/scipy/special/i0e.hpp b/contrib/python/pythran/pythran/pythonic/scipy/special/i0e.hpp
new file mode 100644
index 00000000000..f1ee8428f2b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/scipy/special/i0e.hpp
@@ -0,0 +1,42 @@
+#ifndef PYTHONIC_SCIPY_SPECIAL_I0_HPP
+#define PYTHONIC_SCIPY_SPECIAL_I0_HPP
+
+#include "pythonic/include/scipy/special/i0e.hpp"
+#include "pythonic/scipy/special/chbevl.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+ namespace details
+ {
+ template <class T>
+ double i0e(T x_)
+ {
+ double y;
+ double x = x_;
+ if (x < 0)
+ x = -x;
+ if (x <= 8.0) {
+ y = (x / 2.0) - 2.0;
+ return (chbevl(y, A));
+ }
+
+ return (chbevl(32.0 / x - 2.0, B) / sqrt(x));
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME i0e
+#define NUMPY_NARY_FUNC_SYM details::i0e
+#include "pythonic/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/scipy/special/iv.hpp b/contrib/python/pythran/pythran/pythonic/scipy/special/iv.hpp
new file mode 100644
index 00000000000..06a92836097
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/scipy/special/iv.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_SCIPY_SPECIAL_IV_HPP
+#define PYTHONIC_SCIPY_SPECIAL_IV_HPP
+
+#include "pythonic/include/scipy/special/iv.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+#include "pythonic/utils/boost_local_config.hpp"
+#include <boost/math/special_functions/bessel.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+ namespace details
+ {
+ template <class T0, class T1>
+ double iv(T0 x, T1 y)
+ {
+ using namespace boost::math::policies;
+ return boost::math::cyl_bessel_i(x, y,
+ make_policy(promote_double<true>()));
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME iv
+#define NUMPY_NARY_FUNC_SYM details::iv
+#include "pythonic/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/scipy/special/ivp.hpp b/contrib/python/pythran/pythran/pythonic/scipy/special/ivp.hpp
new file mode 100644
index 00000000000..3834f543558
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/scipy/special/ivp.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_SCIPY_SPECIAL_IVP_HPP
+#define PYTHONIC_SCIPY_SPECIAL_IVP_HPP
+
+#include "pythonic/include/scipy/special/ivp.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+#include "pythonic/utils/boost_local_config.hpp"
+#include <boost/math/special_functions/bessel_prime.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+ namespace details
+ {
+ template <class T0, class T1>
+ double ivp(T0 x, T1 y)
+ {
+ using namespace boost::math::policies;
+ return boost::math::cyl_bessel_i_prime(
+ x, y, make_policy(promote_double<true>()));
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME ivp
+#define NUMPY_NARY_FUNC_SYM details::ivp
+#include "pythonic/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/scipy/special/jv.hpp b/contrib/python/pythran/pythran/pythonic/scipy/special/jv.hpp
new file mode 100644
index 00000000000..944228be942
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/scipy/special/jv.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_SCIPY_SPECIAL_JV_HPP
+#define PYTHONIC_SCIPY_SPECIAL_JV_HPP
+
+#include "pythonic/include/scipy/special/jv.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+#include "pythonic/utils/boost_local_config.hpp"
+#include <boost/math/special_functions/bessel.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+ namespace details
+ {
+ template <class T0, class T1>
+ double jv(T0 x, T1 y)
+ {
+ using namespace boost::math::policies;
+ return boost::math::cyl_bessel_j(x, y,
+ make_policy(promote_double<true>()));
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME jv
+#define NUMPY_NARY_FUNC_SYM details::jv
+#include "pythonic/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/scipy/special/jvp.hpp b/contrib/python/pythran/pythran/pythonic/scipy/special/jvp.hpp
new file mode 100644
index 00000000000..99ad7974c10
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/scipy/special/jvp.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_SCIPY_SPECIAL_JVP_HPP
+#define PYTHONIC_SCIPY_SPECIAL_JVP_HPP
+
+#include "pythonic/include/scipy/special/jvp.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+#include "pythonic/utils/boost_local_config.hpp"
+#include <boost/math/special_functions/bessel_prime.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+ namespace details
+ {
+ template <class T0, class T1>
+ double jvp(T0 x, T1 y)
+ {
+ using namespace boost::math::policies;
+ return boost::math::cyl_bessel_j_prime(
+ x, y, make_policy(promote_double<true>()));
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME jvp
+#define NUMPY_NARY_FUNC_SYM details::jvp
+#include "pythonic/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/scipy/special/kv.hpp b/contrib/python/pythran/pythran/pythonic/scipy/special/kv.hpp
new file mode 100644
index 00000000000..151acd0bb5a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/scipy/special/kv.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_SCIPY_SPECIAL_KV_HPP
+#define PYTHONIC_SCIPY_SPECIAL_KV_HPP
+
+#include "pythonic/include/scipy/special/kv.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+#include "pythonic/utils/boost_local_config.hpp"
+#include <boost/math/special_functions/bessel.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+ namespace details
+ {
+ template <class T0, class T1>
+ double kv(T0 x, T1 y)
+ {
+ using namespace boost::math::policies;
+ return boost::math::cyl_bessel_k(x, y,
+ make_policy(promote_double<true>()));
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME kv
+#define NUMPY_NARY_FUNC_SYM details::kv
+#include "pythonic/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/scipy/special/kvp.hpp b/contrib/python/pythran/pythran/pythonic/scipy/special/kvp.hpp
new file mode 100644
index 00000000000..dcfc6d37913
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/scipy/special/kvp.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_SCIPY_SPECIAL_KVP_HPP
+#define PYTHONIC_SCIPY_SPECIAL_KVP_HPP
+
+#include "pythonic/include/scipy/special/kvp.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+#include "pythonic/utils/boost_local_config.hpp"
+#include <boost/math/special_functions/bessel_prime.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+ namespace details
+ {
+ template <class T0, class T1>
+ double kvp(T0 x, T1 y)
+ {
+ using namespace boost::math::policies;
+ return boost::math::cyl_bessel_k_prime(
+ x, y, make_policy(promote_double<true>()));
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME kvp
+#define NUMPY_NARY_FUNC_SYM details::kvp
+#include "pythonic/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/scipy/special/ndtr.hpp b/contrib/python/pythran/pythran/pythonic/scipy/special/ndtr.hpp
new file mode 100644
index 00000000000..4245fbf4e78
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/scipy/special/ndtr.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_SCIPY_SPECIAL_NDTR_HPP
+#define PYTHONIC_SCIPY_SPECIAL_NDTR_HPP
+
+#include "pythonic/include/scipy/special/ndtr.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+#include "pythonic/utils/boost_local_config.hpp"
+#include <boost/math/distributions/normal.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+ namespace details
+ {
+ template <class T>
+ double ndtr(T x)
+ {
+ using namespace boost::math::policies;
+ boost::math::normal dist(0.0, 1.0);
+ return cdf(dist, x);
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME ndtr
+#define NUMPY_NARY_FUNC_SYM details::ndtr
+#include "pythonic/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/scipy/special/ndtri.hpp b/contrib/python/pythran/pythran/pythonic/scipy/special/ndtri.hpp
new file mode 100644
index 00000000000..f19df228562
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/scipy/special/ndtri.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_SCIPY_SPECIAL_NDTRI_HPP
+#define PYTHONIC_SCIPY_SPECIAL_NDTRI_HPP
+
+#include "pythonic/include/scipy/special/ndtri.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+#include "pythonic/utils/boost_local_config.hpp"
+#include <boost/math/distributions/normal.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+ namespace details
+ {
+ template <class T>
+ double ndtri(T x)
+ {
+ using namespace boost::math::policies;
+ boost::math::normal dist(0.0, 1.0);
+ return quantile(dist, x);
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME ndtri
+#define NUMPY_NARY_FUNC_SYM details::ndtri
+#include "pythonic/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/scipy/special/spherical_jn.hpp b/contrib/python/pythran/pythran/pythonic/scipy/special/spherical_jn.hpp
new file mode 100644
index 00000000000..643847c53a9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/scipy/special/spherical_jn.hpp
@@ -0,0 +1,45 @@
+#ifndef PYTHONIC_SCIPY_SPECIAL_SPHERICAL_JN_HPP
+#define PYTHONIC_SCIPY_SPECIAL_SPHERICAL_JN_HPP
+
+#include "pythonic/include/scipy/special/spherical_jn.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+#include "pythonic/utils/boost_local_config.hpp"
+#include <boost/math/special_functions/bessel.hpp>
+#include <boost/math/special_functions/bessel_prime.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+ namespace details
+ {
+ template <class T0, class T1>
+ double spherical_jn(T0 v, T1 x, bool derivative)
+ {
+ assert(v == (long)v &&
+ "only supported for integral value as first arg");
+ using namespace boost::math::policies;
+ if (derivative) {
+ return boost::math::sph_bessel_prime(
+ v, x, make_policy(promote_double<true>()));
+ } else {
+ return boost::math::sph_bessel(v, x,
+ make_policy(promote_double<true>()));
+ }
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME spherical_jn
+#define NUMPY_NARY_FUNC_SYM details::spherical_jn
+#include "pythonic/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/scipy/special/spherical_yn.hpp b/contrib/python/pythran/pythran/pythonic/scipy/special/spherical_yn.hpp
new file mode 100644
index 00000000000..cde3816dff4
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/scipy/special/spherical_yn.hpp
@@ -0,0 +1,45 @@
+#ifndef PYTHONIC_SCIPY_SPECIAL_SPHERICAL_YN_HPP
+#define PYTHONIC_SCIPY_SPECIAL_SPHERICAL_YN_HPP
+
+#include "pythonic/include/scipy/special/spherical_yn.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+#include "pythonic/utils/boost_local_config.hpp"
+#include <boost/math/special_functions/bessel.hpp>
+#include <boost/math/special_functions/bessel_prime.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+ namespace details
+ {
+ template <class T0, class T1>
+ double spherical_yn(T0 v, T1 x, bool derivative)
+ {
+ assert(v == (long)v &&
+ "only supported for integral value as first arg");
+ using namespace boost::math::policies;
+ if (derivative) {
+ return boost::math::sph_neumann_prime(
+ v, x, make_policy(promote_double<true>()));
+ } else {
+ return boost::math::sph_neumann(v, x,
+ make_policy(promote_double<true>()));
+ }
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME spherical_yn
+#define NUMPY_NARY_FUNC_SYM details::spherical_yn
+#include "pythonic/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/scipy/special/yv.hpp b/contrib/python/pythran/pythran/pythonic/scipy/special/yv.hpp
new file mode 100644
index 00000000000..7367ea69ef5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/scipy/special/yv.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_SCIPY_SPECIAL_YV_HPP
+#define PYTHONIC_SCIPY_SPECIAL_YV_HPP
+
+#include "pythonic/include/scipy/special/yv.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+#include "pythonic/utils/boost_local_config.hpp"
+#include <boost/math/special_functions/bessel.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+ namespace details
+ {
+ template <class T0, class T1>
+ double yv(T0 x, T1 y)
+ {
+ using namespace boost::math::policies;
+ return boost::math::cyl_neumann(x, y,
+ make_policy(promote_double<true>()));
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME yv
+#define NUMPY_NARY_FUNC_SYM details::yv
+#include "pythonic/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/scipy/special/yvp.hpp b/contrib/python/pythran/pythran/pythonic/scipy/special/yvp.hpp
new file mode 100644
index 00000000000..f08bf1fd954
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/scipy/special/yvp.hpp
@@ -0,0 +1,37 @@
+#ifndef PYTHONIC_SCIPY_SPECIAL_YVP_HPP
+#define PYTHONIC_SCIPY_SPECIAL_YVP_HPP
+
+#include "pythonic/include/scipy/special/yvp.hpp"
+
+#include "pythonic/types/ndarray.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/utils/numpy_traits.hpp"
+
+#include "pythonic/utils/boost_local_config.hpp"
+#include <boost/math/special_functions/bessel_prime.hpp>
+
+PYTHONIC_NS_BEGIN
+
+namespace scipy
+{
+ namespace special
+ {
+ namespace details
+ {
+ template <class T0, class T1>
+ double yvp(T0 x, T1 y)
+ {
+ using namespace boost::math::policies;
+ return boost::math::cyl_neumann_prime(
+ x, y, make_policy(promote_double<true>()));
+ }
+ }
+
+#define NUMPY_NARY_FUNC_NAME yvp
+#define NUMPY_NARY_FUNC_SYM details::yvp
+#include "pythonic/types/numpy_nary_expr.hpp"
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/string/ascii_letters.hpp b/contrib/python/pythran/pythran/pythonic/string/ascii_letters.hpp
new file mode 100644
index 00000000000..686aa09ccac
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/string/ascii_letters.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_STRING_ASCII_LETTERS_HPP
+#define PYTHONIC_STRING_ASCII_LETTERS_HPP
+
+#include "pythonic/include/string/ascii_letters.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/string/ascii_lowercase.hpp b/contrib/python/pythran/pythran/pythonic/string/ascii_lowercase.hpp
new file mode 100644
index 00000000000..07f23ad9972
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/string/ascii_lowercase.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_STRING_ASCII_LOWERCASE_HPP
+#define PYTHONIC_STRING_ASCII_LOWERCASE_HPP
+
+#include "pythonic/include/string/ascii_lowercase.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/string/ascii_uppercase.hpp b/contrib/python/pythran/pythran/pythonic/string/ascii_uppercase.hpp
new file mode 100644
index 00000000000..2dc0dacf1f5
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/string/ascii_uppercase.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_STRING_ASCII_UPPERCASE_HPP
+#define PYTHONIC_STRING_ASCII_UPPERCASE_HPP
+
+#include "pythonic/include/string/ascii_uppercase.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/string/digits.hpp b/contrib/python/pythran/pythran/pythonic/string/digits.hpp
new file mode 100644
index 00000000000..e4885aa3769
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/string/digits.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_STRING_DIGITS_HPP
+#define PYTHONIC_STRING_DIGITS_HPP
+
+#include "pythonic/include/string/digits.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/string/find.hpp b/contrib/python/pythran/pythran/pythonic/string/find.hpp
new file mode 100644
index 00000000000..da093eed90a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/string/find.hpp
@@ -0,0 +1,22 @@
+#ifndef PYTHONIC_STRING_FIND_HPP
+#define PYTHONIC_STRING_FIND_HPP
+
+#include "pythonic/include/string/find.hpp"
+
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/types/str.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace string
+{
+
+ template <class T>
+ long find(types::str const &s, T &&val)
+ {
+ return s.find(std::forward<T>(val));
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/string/hexdigits.hpp b/contrib/python/pythran/pythran/pythonic/string/hexdigits.hpp
new file mode 100644
index 00000000000..5aee9f2cd07
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/string/hexdigits.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_STRING_HEXDIGITS_HPP
+#define PYTHONIC_STRING_HEXDIGITS_HPP
+
+#include "pythonic/include/string/hexdigits.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/string/octdigits.hpp b/contrib/python/pythran/pythran/pythonic/string/octdigits.hpp
new file mode 100644
index 00000000000..4659e18985e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/string/octdigits.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_STRING_OCTDIGITS_HPP
+#define PYTHONIC_STRING_OCTDIGITS_HPP
+
+#include "pythonic/include/string/octdigits.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/time/sleep.hpp b/contrib/python/pythran/pythran/pythonic/time/sleep.hpp
new file mode 100644
index 00000000000..7da71a02924
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/time/sleep.hpp
@@ -0,0 +1,24 @@
+#ifndef PYTHONIC_TIME_SLEEP_HPP
+#define PYTHONIC_TIME_SLEEP_HPP
+
+#include "pythonic/include/time/sleep.hpp"
+#include "pythonic/utils/functor.hpp"
+#include "pythonic/builtins/None.hpp"
+
+#include <thread>
+#include <chrono>
+
+PYTHONIC_NS_BEGIN
+
+namespace time
+{
+
+ types::none_type sleep(double const value)
+ {
+ std::this_thread::sleep_for(std::chrono::duration<double>(value));
+ return builtins::None;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/time/time.hpp b/contrib/python/pythran/pythran/pythonic/time/time.hpp
new file mode 100644
index 00000000000..44ed54c76e9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/time/time.hpp
@@ -0,0 +1,25 @@
+#ifndef PYTHONIC_TIME_TIME_HPP
+#define PYTHONIC_TIME_TIME_HPP
+
+#include "pythonic/include/time/time.hpp"
+#include "pythonic/utils/functor.hpp"
+
+#include <chrono>
+
+PYTHONIC_NS_BEGIN
+
+namespace time
+{
+
+ double time()
+ {
+ std::chrono::time_point<std::chrono::steady_clock> tp =
+ std::chrono::steady_clock::now();
+ return std::chrono::duration_cast<std::chrono::milliseconds>(
+ tp.time_since_epoch()).count() /
+ 1000.;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/types/cfun.hpp b/contrib/python/pythran/pythran/pythonic/types/cfun.hpp
new file mode 100644
index 00000000000..f5b355a258a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/types/cfun.hpp
@@ -0,0 +1,53 @@
+#ifndef PYTHONIC_TYPES_CFUN_HPP
+#define PYTHONIC_TYPES_CFUN_HPP
+
+#include "pythonic/include/types/cfun.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace types
+{
+ template <class ReturnType, class... ArgsType>
+ cfun<ReturnType(ArgsType...)>::cfun(ReturnType (*fun)(ArgsType...))
+ : ptr(fun)
+ {
+ }
+
+ template <class ReturnType, class... ArgsType>
+ ReturnType cfun<ReturnType(ArgsType...)>::operator()(ArgsType... args) const
+ {
+ return (*ptr)(args...);
+ }
+}
+PYTHONIC_NS_END
+
+#ifdef ENABLE_PYTHON_MODULE
+
+PYTHONIC_NS_BEGIN
+
+template <class R, class... Args>
+PyObject *
+to_python<types::cfun<R(Args...)>>::convert(types::cfun<R(Args...)> const &v)
+{
+ return PyCapsule_New(v.ptr, nullptr, nullptr);
+}
+
+template <class R, class... Args>
+bool from_python<types::cfun<R(Args...)>>::is_convertible(PyObject *obj)
+{
+ return PyCapsule_CheckExact(obj);
+}
+
+template <class R, class... Args>
+types::cfun<R(Args...)>
+from_python<types::cfun<R(Args...)>>::convert(PyObject *obj)
+{
+ void *ptr = PyCapsule_GetPointer(
+ obj, PyCapsule_GetName(obj) /* avoid the string check*/);
+ return {reinterpret_cast<R (*)(Args...)>(ptr)};
+}
+PYTHONIC_NS_END
+
+#endif
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/types/clongdouble.hpp b/contrib/python/pythran/pythran/pythonic/types/clongdouble.hpp
new file mode 100644
index 00000000000..057a2b9cb60
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/types/clongdouble.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_TYPES_CLONGDOUBLE_HPP
+#define PYTHONIC_TYPES_CLONGDOUBLE_HPP
+
+#include "pythonic/include/types/clongdouble.hpp"
+#include "pythonic/types/complex.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/types/complex256.hpp b/contrib/python/pythran/pythran/pythonic/types/complex256.hpp
new file mode 100644
index 00000000000..87e1e1eb6c9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/types/complex256.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_TYPES_COMPLEX256_HPP
+#define PYTHONIC_TYPES_COMPLEX256_HPP
+
+#include "pythonic/include/types/complex256.hpp"
+#include "pythonic/types/complex.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/types/complex64.hpp b/contrib/python/pythran/pythran/pythonic/types/complex64.hpp
new file mode 100644
index 00000000000..09f1bdc4465
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/types/complex64.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_TYPES_COMPLEX64_HPP
+#define PYTHONIC_TYPES_COMPLEX64_HPP
+
+#include "pythonic/include/types/complex64.hpp"
+#include "pythonic/types/complex.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/types/file.hpp b/contrib/python/pythran/pythran/pythonic/types/file.hpp
new file mode 100644
index 00000000000..04c72d46038
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/types/file.hpp
@@ -0,0 +1,340 @@
+#ifndef PYTHONIC_TYPES_FILE_HPP
+#define PYTHONIC_TYPES_FILE_HPP
+
+#include "pythonic/include/types/file.hpp"
+
+#include "pythonic/builtins/IOError.hpp"
+#include "pythonic/builtins/RuntimeError.hpp"
+#include "pythonic/builtins/StopIteration.hpp"
+#include "pythonic/builtins/ValueError.hpp"
+#include "pythonic/types/NoneType.hpp"
+#include "pythonic/types/assignable.hpp"
+#include "pythonic/types/attr.hpp"
+#include "pythonic/types/list.hpp"
+#include "pythonic/types/str.hpp"
+#include "pythonic/utils/allocate.hpp"
+#include "pythonic/utils/shared_ref.hpp"
+
+#include <cstdio>
+#include <cstring>
+#include <fstream>
+#include <iterator>
+#include <string>
+
+#ifdef _WIN32
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+PYTHONIC_NS_BEGIN
+
+namespace types
+{
+
+ /// _file implementation
+
+ inline _file::_file() : f(nullptr)
+ {
+ }
+
+ // TODO : no check on file existance?
+ inline _file::_file(types::str const &filename, types::str const &strmode)
+ : f(fopen(filename.c_str(), strmode.c_str()))
+ {
+ }
+
+ inline FILE *_file::operator*() const
+ {
+ return f;
+ }
+
+ inline _file::~_file()
+ {
+ if (f)
+ fclose(f);
+ }
+
+ /// file implementation
+
+ // Constructors
+ inline file::file() : file_iterator(), data(utils::no_memory())
+ {
+ }
+
+ inline file::file(types::str const &filename, types::str const &strmode)
+ : file_iterator(), data(utils::no_memory()), mode(strmode),
+ name(filename), newlines('\n')
+ {
+ open(filename, strmode);
+ if (mode.find_first_of("r+") != -1)
+ *(file_iterator *)this = file_iterator(*this);
+ }
+
+ // Iterators
+ inline file::iterator file::begin()
+ {
+ return *this;
+ }
+
+ inline file::iterator file::end()
+ {
+ return {};
+ }
+
+ // Modifiers
+ inline void file::open(types::str const &filename, types::str const &strmode)
+ {
+ const char *smode = strmode.c_str();
+ // Python enforces that the mode, after stripping 'U', begins with 'r',
+ // 'w' || 'a'.
+ if (*smode == 'U') {
+ ++smode;
+ } // Not implemented yet
+
+ data = utils::shared_ref<container_type>(filename, smode);
+ if (!**data)
+ throw types::IOError("Couldn't open file " + filename);
+ is_open = true;
+ }
+
+ inline void file::close()
+ {
+ fclose(**data);
+ data->f = nullptr;
+ is_open = false;
+ }
+
+ inline bool file::closed() const
+ {
+ return !is_open;
+ }
+
+ inline types::str const &file::getmode() const
+ {
+ return mode;
+ }
+
+ inline types::str const &file::getname() const
+ {
+ return name;
+ }
+
+ inline types::str const &file::getnewlines() const
+ {
+ // Python seems to always return none... Doing the same here
+ return newlines;
+ }
+
+ inline bool file::eof()
+ {
+ return ::feof(**data);
+ }
+
+ inline void file::flush()
+ {
+ if (!is_open)
+ throw ValueError("I/O operation on closed file");
+ fflush(**data);
+ }
+
+ inline long file::fileno() const
+ {
+ if (!is_open)
+ throw ValueError("I/O operation on closed file");
+ return ::fileno(**data);
+ }
+
+ inline bool file::isatty() const
+ {
+ if (!is_open)
+ throw ValueError("I/O operation on closed file");
+ return ::isatty(this->fileno());
+ }
+
+ inline types::str file::read(long size)
+ {
+ if (!is_open)
+ throw ValueError("I/O operation on closed file");
+ if (mode.find_first_of("r+") == -1)
+ throw IOError("File not open for reading");
+ if (size == 0 || (feof(**data) && mode.find_first_of("ra") == -1))
+ return types::str();
+ long curr_pos = tell();
+ seek(0, SEEK_END);
+ size = size < 0 ? tell() - curr_pos : size;
+ seek(curr_pos);
+ char *content = utils::allocate<char>(size);
+
+ // This part needs a new implementation of types::str(char*) to avoid
+ // unnecessary copy.
+ types::str res(content, fread(content, sizeof(char), size, **data));
+ utils::deallocate(content);
+ return res;
+ }
+
+ inline types::str file::readline(long size)
+ {
+ if (!is_open)
+ throw ValueError("I/O operation on closed file");
+ if (mode.find_first_of("r+") == -1)
+ throw IOError("File not open for reading");
+ constexpr static long BUFFER_SIZE = 1024;
+ types::str res;
+ char read_str[BUFFER_SIZE];
+
+ for (long i = 0; i < size; i += BUFFER_SIZE) {
+ // +1 because we read the last chunk so we don't want to count \0
+ if (fgets(read_str, std::min(BUFFER_SIZE - 1, size - i) + 1, **data))
+ res += read_str;
+ if (feof(**data) || res[res.size() - 1] == "\n")
+ break;
+ }
+ return res;
+ }
+
+ inline types::list<types::str> file::readlines(long sizehint)
+ {
+ // Official python doc specifies that sizehint is used as a max of chars
+ // But it has not been implemented in the standard python interpreter...
+ types::str str;
+ types::list<types::str> lst(0);
+ while ((str = readline()))
+ lst.push_back(str);
+ return lst;
+ }
+
+ inline void file::seek(long offset, long whence)
+ {
+ if (!is_open)
+ throw ValueError("I/O operation on closed file");
+ if (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END)
+ throw IOError("file.seek() : Invalid argument.");
+ fseek(**data, offset, whence);
+ }
+
+ inline long file::tell() const
+ {
+ if (!is_open)
+ throw ValueError("I/O operation on closed file");
+ return ftell(**data);
+ }
+
+ inline void file::truncate(long size)
+ {
+ if (!is_open)
+ throw ValueError("I/O operation on closed file");
+ if (mode.find_first_of("wa+") == -1)
+ throw IOError("file.write() : File not open for writing.");
+ if (size < 0)
+ size = this->tell();
+#ifdef _WIN32
+ long error = _chsize_s(fileno(), size);
+#else
+ long error = ftruncate(fileno(), size);
+#endif
+ if (error == -1)
+ throw RuntimeError(strerror(errno));
+ }
+
+ inline long file::write(types::str const &str)
+ {
+ if (!is_open)
+ throw ValueError("I/O operation on closed file");
+ if (mode.find_first_of("wa+") == -1)
+ throw IOError("file.write() : File not open for writing.");
+ return fwrite(str.c_str(), sizeof(char), str.size(), **data);
+ }
+
+ template <class T>
+ void file::writelines(T const &seq)
+ {
+ auto end = seq.end();
+ for (auto it = seq.begin(); it != end; ++it)
+ write(*it);
+ }
+
+ /// file_iterator implementation
+ // TODO : What if the file disappears before the end?
+ // Like in :
+ // for line in open("myfile"):
+ // print line
+ inline file_iterator::file_iterator(file &ref)
+ : f(&ref), set(false), curr(), position(ref.tell())
+ {
+ }
+
+ inline file_iterator::file_iterator()
+ : f(nullptr), set(false), curr(),
+ position(std::numeric_limits<long>::max()){};
+
+ inline bool file_iterator::operator==(file_iterator const &f2) const
+ {
+ return position == f2.position;
+ }
+
+ inline bool file_iterator::operator!=(file_iterator const &f2) const
+ {
+ return position != f2.position;
+ }
+
+ inline bool file_iterator::operator<(file_iterator const &f2) const
+ {
+ // Not really elegant...
+ // Equivalent to 'return *this != f2;'
+ return position < f2.position;
+ }
+
+ inline file_iterator &file_iterator::operator++()
+ {
+ if (f->eof())
+ return *this;
+ operator*();
+ set = false;
+ operator*();
+ position = f->eof() ? std::numeric_limits<long>::max() : f->tell();
+ return *this;
+ }
+
+ inline types::str file_iterator::operator*() const
+ {
+ if (!set) {
+ curr = f->readline();
+ set = true;
+ }
+ return curr.chars(); // to make a copy
+ }
+} // namespace types
+PYTHONIC_NS_END
+
+/* pythran attribute system { */
+PYTHONIC_NS_BEGIN
+
+namespace builtins
+{
+ inline bool getattr(types::attr::CLOSED, types::file const &f)
+ {
+ return f.closed();
+ }
+
+ inline types::str const &getattr(types::attr::MODE, types::file const &f)
+ {
+ return f.getmode();
+ }
+
+ inline types::str const &getattr(types::attr::NAME, types::file const &f)
+ {
+ return f.getname();
+ }
+
+ // Python seems to always return none... Doing the same.
+ inline types::none_type getattr(types::attr::NEWLINES, types::file const &f)
+ {
+ return builtins::None;
+ }
+} // namespace builtins
+PYTHONIC_NS_END
+
+/* } */
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/types/finfo.hpp b/contrib/python/pythran/pythran/pythonic/types/finfo.hpp
new file mode 100644
index 00000000000..e3c3d7d2785
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/types/finfo.hpp
@@ -0,0 +1,41 @@
+#ifndef PYTHONIC_TYPES_FINFO_HPP
+#define PYTHONIC_TYPES_FINFO_HPP
+
+#include "pythonic/include/types/finfo.hpp"
+
+#include "pythonic/types/attr.hpp"
+
+#include <limits>
+
+PYTHONIC_NS_BEGIN
+
+namespace types
+{
+ template <class T>
+ T finfo<std::complex<T>>::eps() const
+ {
+ return std::numeric_limits<T>::epsilon();
+ }
+
+ template <class T>
+ T finfo<T>::eps() const
+ {
+ return std::numeric_limits<T>::epsilon();
+ }
+}
+PYTHONIC_NS_END
+
+/* pythran attribute system { */
+PYTHONIC_NS_BEGIN
+namespace builtins
+{
+ template <class T>
+ auto getattr(types::attr::EPS, pythonic::types::finfo<T> const &f)
+ -> decltype(f.eps())
+ {
+ return f.eps();
+ }
+}
+PYTHONIC_NS_END
+/* } */
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/types/float128.hpp b/contrib/python/pythran/pythran/pythonic/types/float128.hpp
new file mode 100644
index 00000000000..0943827ff30
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/types/float128.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_TYPES_FLOAT128_HPP
+#define PYTHONIC_TYPES_FLOAT128_HPP
+
+#include "pythonic/include/types/float128.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/types/generator.hpp b/contrib/python/pythran/pythran/pythonic/types/generator.hpp
new file mode 100644
index 00000000000..19f8efb53e6
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/types/generator.hpp
@@ -0,0 +1,75 @@
+#ifndef PYTHONIC_TYPES_GENERATOR_HPP
+#define PYTHONIC_TYPES_GENERATOR_HPP
+
+#include "pythonic/include/types/generator.hpp"
+
+#include "pythonic/builtins/StopIteration.hpp"
+#include <iterator>
+
+PYTHONIC_NS_BEGIN
+
+namespace types
+{
+ template <class T>
+ generator_iterator<T>::generator_iterator()
+ : the_generator()
+ {
+ the_generator.__generator_state = -1;
+ } // this represents the end
+
+ template <class T>
+ generator_iterator<T>::generator_iterator(T const &a_generator)
+ : the_generator(a_generator)
+ {
+ }
+
+ template <class T>
+ generator_iterator<T> &generator_iterator<T>::operator++()
+ {
+ try {
+ the_generator.next();
+ } catch (types::StopIteration const &) {
+ the_generator.__generator_state = -1;
+ }
+ return *this;
+ }
+
+ template <class T>
+ typename T::result_type generator_iterator<T>::operator*() const
+ {
+ return *the_generator;
+ }
+
+ template <class T>
+ bool generator_iterator<T>::
+ operator!=(generator_iterator<T> const &other) const
+ {
+ assert(other.the_generator.__generator_state == -1 ||
+ the_generator.__generator_state == -1);
+ return the_generator.__generator_state !=
+ other.the_generator.__generator_state;
+ }
+
+ template <class T>
+ bool generator_iterator<T>::
+ operator==(generator_iterator<T> const &other) const
+ {
+ assert(other.the_generator.__generator_state == -1 ||
+ the_generator.__generator_state == -1);
+ return the_generator.__generator_state ==
+ other.the_generator.__generator_state;
+ }
+
+ template <class T>
+ bool generator_iterator<T>::
+ operator<(generator_iterator<T> const &other) const
+ {
+ assert(other.the_generator.__generator_state == -1 ||
+ the_generator.__generator_state == -1);
+ return the_generator.__generator_state !=
+ other.the_generator.__generator_state;
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/types/int16.hpp b/contrib/python/pythran/pythran/pythonic/types/int16.hpp
new file mode 100644
index 00000000000..a797e46f77e
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/types/int16.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_TYPES_INT16_HPP
+#define PYTHONIC_TYPES_INT16_HPP
+
+#include "pythonic/include/types/int16.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/types/intc.hpp b/contrib/python/pythran/pythran/pythonic/types/intc.hpp
new file mode 100644
index 00000000000..44151099bad
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/types/intc.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_TYPES_INTC_HPP
+#define PYTHONIC_TYPES_INTC_HPP
+
+#include "pythonic/include/types/intc.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/types/intp.hpp b/contrib/python/pythran/pythran/pythonic/types/intp.hpp
new file mode 100644
index 00000000000..7437e5720d9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/types/intp.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_TYPES_INTP_HPP
+#define PYTHONIC_TYPES_INTP_HPP
+
+#include "pythonic/include/types/intp.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/types/longdouble.hpp b/contrib/python/pythran/pythran/pythonic/types/longdouble.hpp
new file mode 100644
index 00000000000..b3944cea6a0
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/types/longdouble.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_TYPES_LONGDOUBLE_HPP
+#define PYTHONIC_TYPES_LONGDOUBLE_HPP
+
+#include "pythonic/include/types/longdouble.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/types/pointer.hpp b/contrib/python/pythran/pythran/pythonic/types/pointer.hpp
new file mode 100644
index 00000000000..7cca903197b
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/types/pointer.hpp
@@ -0,0 +1,85 @@
+#ifndef PYTHONIC_TYPES_POINTER_HPP
+#define PYTHONIC_TYPES_POINTER_HPP
+
+#include "pythonic/include/types/pointer.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace types
+{
+
+ template <class T>
+ typename pointer<T>::reference pointer<T>::operator[](long i)
+ {
+ return data[i];
+ }
+
+ template <class T>
+ typename pointer<T>::value_type pointer<T>::operator[](long i) const
+ {
+ return data[i];
+ }
+
+ template <class T>
+ typename pointer<T>::reference pointer<T>::fast(long i)
+ {
+ return data[i];
+ }
+
+ template <class T>
+ typename pointer<T>::value_type pointer<T>::fast(long i) const
+ {
+ return data[i];
+ }
+}
+PYTHONIC_NS_END
+
+namespace std
+{
+ template <size_t I, class T>
+ typename pythonic::types::pointer<T>::reference
+ get(pythonic::types::pointer<T> &t)
+ {
+ return t[I];
+ }
+
+ template <size_t I, class T>
+ typename pythonic::types::pointer<T>::value_type
+ get(pythonic::types::pointer<T> const &t)
+ {
+ return t[I];
+ }
+
+ template <size_t I, class T>
+ typename pythonic::types::pointer<T>::value_type
+ get(pythonic::types::pointer<T> &&t)
+ {
+ return t[I];
+ }
+}
+
+#ifdef ENABLE_PYTHON_MODULE
+
+PYTHONIC_NS_BEGIN
+
+template <typename T>
+PyObject *to_python<types::pointer<T>>::convert(types::pointer<T> const &v)
+{
+ return nullptr;
+}
+
+template <class T>
+bool from_python<types::pointer<T>>::is_convertible(PyObject *obj)
+{
+ return false;
+}
+template <class T>
+types::pointer<T> from_python<types::pointer<T>>::convert(PyObject *obj)
+{
+ return {nullptr};
+}
+PYTHONIC_NS_END
+
+#endif
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/types/static_if.hpp b/contrib/python/pythran/pythran/pythonic/types/static_if.hpp
new file mode 100644
index 00000000000..e988a136194
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/types/static_if.hpp
@@ -0,0 +1,5 @@
+#ifndef PYTHONIC_TYPES_STATIC_IF_HPP
+#define PYTHONIC_TYPES_STATIC_IF_HPP
+#include "pythonic/include/types/static_if.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/types/uint16.hpp b/contrib/python/pythran/pythran/pythonic/types/uint16.hpp
new file mode 100644
index 00000000000..099575852d9
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/types/uint16.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_TYPES_UINT16_HPP
+#define PYTHONIC_TYPES_UINT16_HPP
+
+#include "pythonic/include/types/uint16.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/types/uint32.hpp b/contrib/python/pythran/pythran/pythonic/types/uint32.hpp
new file mode 100644
index 00000000000..f95a5464102
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/types/uint32.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_TYPES_UINT32_HPP
+#define PYTHONIC_TYPES_UINT32_HPP
+
+#include "pythonic/include/types/uint32.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/types/uint64.hpp b/contrib/python/pythran/pythran/pythonic/types/uint64.hpp
new file mode 100644
index 00000000000..f09480841de
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/types/uint64.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_TYPES_UINT64_HPP
+#define PYTHONIC_TYPES_UINT64_HPP
+
+#include "pythonic/include/types/uint64.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/types/uint8.hpp b/contrib/python/pythran/pythran/pythonic/types/uint8.hpp
new file mode 100644
index 00000000000..294be84b495
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/types/uint8.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_TYPES_UINT8_HPP
+#define PYTHONIC_TYPES_UINT8_HPP
+
+#include "pythonic/include/types/uint8.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/types/uintc.hpp b/contrib/python/pythran/pythran/pythonic/types/uintc.hpp
new file mode 100644
index 00000000000..db32c2d704a
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/types/uintc.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_TYPES_UINTC_HPP
+#define PYTHONIC_TYPES_UINTC_HPP
+
+#include "pythonic/include/types/uintc.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/types/uintp.hpp b/contrib/python/pythran/pythran/pythonic/types/uintp.hpp
new file mode 100644
index 00000000000..af7c81846c2
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/types/uintp.hpp
@@ -0,0 +1,6 @@
+#ifndef PYTHONIC_TYPES_UINTP_HPP
+#define PYTHONIC_TYPES_UINTP_HPP
+
+#include "pythonic/include/types/uintp.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/utils/boost_local_config.hpp b/contrib/python/pythran/pythran/pythonic/utils/boost_local_config.hpp
new file mode 100644
index 00000000000..bb499218157
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/utils/boost_local_config.hpp
@@ -0,0 +1,9 @@
+#ifndef BOOST_MATH_THREAD_LOCAL
+#define BOOST_MATH_THREAD_LOCAL thread_local
+#endif
+#ifndef BOOST_MATH_OVERFLOW_ERROR_POLICY
+#define BOOST_MATH_OVERFLOW_ERROR_POLICY ignore_error
+#endif
+#ifndef BOOST_MATH_DOMAIN_ERROR_POLICY
+#define BOOST_MATH_DOMAIN_ERROR_POLICY ignore_error
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/utils/fwd.hpp b/contrib/python/pythran/pythran/pythonic/utils/fwd.hpp
new file mode 100644
index 00000000000..66438d6561c
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/utils/fwd.hpp
@@ -0,0 +1,18 @@
+#ifndef PYTHONIC_UTILS_FWD_HPP
+#define PYTHONIC_UTILS_FWD_HPP
+
+#include "pythonic/include/utils/fwd.hpp"
+
+PYTHONIC_NS_BEGIN
+
+namespace utils
+{
+
+ template <typename... Types>
+ void fwd(Types const &... types)
+ {
+ }
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/utils/tags.hpp b/contrib/python/pythran/pythran/pythonic/utils/tags.hpp
new file mode 100644
index 00000000000..aa4066a7365
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/utils/tags.hpp
@@ -0,0 +1,7 @@
+#ifndef PYTHONIC_UTILS_TAGS_HPP
+#define PYTHONIC_UTILS_TAGS_HPP
+
+#include "pythonic/include/utils/tags.hpp"
+#include "pythonic/types/traits.hpp"
+
+#endif
diff --git a/contrib/python/pythran/pythran/pythonic/utils/yield.hpp b/contrib/python/pythran/pythran/pythonic/utils/yield.hpp
new file mode 100644
index 00000000000..c9858257e92
--- /dev/null
+++ b/contrib/python/pythran/pythran/pythonic/utils/yield.hpp
@@ -0,0 +1,28 @@
+#ifndef PYTHRAN_UTILS_YIELD_HPP
+#define PYTHRAN_UTILS_YIELD_HPP
+
+#include "pythonic/include/utils/yield.hpp"
+
+/*
+ * This contains base class for yielders
+ */
+
+#include "pythonic/types/generator.hpp"
+
+PYTHONIC_NS_BEGIN
+inline yielder::yielder() : __generator_state(0)
+{
+}
+
+inline bool yielder::operator!=(yielder const &other) const
+{
+ return __generator_state != other.__generator_state;
+}
+
+inline bool yielder::operator==(yielder const &other) const
+{
+ return __generator_state == other.__generator_state;
+}
+PYTHONIC_NS_END
+
+#endif
diff --git a/contrib/python/pythran/pythran/xsimd/arch/xsimd_avx512cd.hpp b/contrib/python/pythran/pythran/xsimd/arch/xsimd_avx512cd.hpp
new file mode 100644
index 00000000000..95f3f1df8f6
--- /dev/null
+++ b/contrib/python/pythran/pythran/xsimd/arch/xsimd_avx512cd.hpp
@@ -0,0 +1,28 @@
+/***************************************************************************
+ * Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and *
+ * Martin Renou *
+ * Copyright (c) QuantStack *
+ * Copyright (c) Serge Guelton *
+ * *
+ * Distributed under the terms of the BSD 3-Clause License. *
+ * *
+ * The full license is in the file LICENSE, distributed with this software. *
+ ****************************************************************************/
+
+#ifndef XSIMD_AVX512CD_HPP
+#define XSIMD_AVX512CD_HPP
+
+#include "../types/xsimd_avx512cd_register.hpp"
+
+namespace xsimd
+{
+
+ namespace kernel
+ {
+ // Nothing there yet.
+
+ }
+
+}
+
+#endif
diff --git a/contrib/python/pythran/pythran/xsimd/arch/xsimd_avx512dq.hpp b/contrib/python/pythran/pythran/xsimd/arch/xsimd_avx512dq.hpp
new file mode 100644
index 00000000000..4788d19e948
--- /dev/null
+++ b/contrib/python/pythran/pythran/xsimd/arch/xsimd_avx512dq.hpp
@@ -0,0 +1,212 @@
+/***************************************************************************
+ * Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and *
+ * Martin Renou *
+ * Copyright (c) QuantStack *
+ * Copyright (c) Serge Guelton *
+ * *
+ * Distributed under the terms of the BSD 3-Clause License. *
+ * *
+ * The full license is in the file LICENSE, distributed with this software. *
+ ****************************************************************************/
+
+#ifndef XSIMD_AVX512_DQHPP
+#define XSIMD_AVX512_D_HPP
+
+#include "../types/xsimd_avx512dq_register.hpp"
+
+namespace xsimd
+{
+
+ namespace kernel
+ {
+ using namespace types;
+
+ // bitwise_and
+ template <class A>
+ XSIMD_INLINE batch<float, A> bitwise_and(batch<float, A> const& self, batch<float, A> const& other, requires_arch<avx512dq>) noexcept
+ {
+ return _mm512_and_ps(self, other);
+ }
+ template <class A>
+ XSIMD_INLINE batch<double, A> bitwise_and(batch<double, A> const& self, batch<double, A> const& other, requires_arch<avx512dq>) noexcept
+ {
+ return _mm512_and_pd(self, other);
+ }
+
+ // bitwise_andnot
+ template <class A>
+ XSIMD_INLINE batch<float, A> bitwise_andnot(batch<float, A> const& self, batch<float, A> const& other, requires_arch<avx512dq>) noexcept
+ {
+ return _mm512_andnot_ps(other, self);
+ }
+ template <class A>
+ XSIMD_INLINE batch<double, A> bitwise_andnot(batch<double, A> const& self, batch<double, A> const& other, requires_arch<avx512dq>) noexcept
+ {
+ return _mm512_andnot_pd(other, self);
+ }
+
+ // bitwise_not
+ template <class A>
+ XSIMD_INLINE batch<float, A> bitwise_not(batch<float, A> const& self, requires_arch<avx512f>) noexcept
+ {
+ return _mm512_xor_ps(self, _mm512_castsi512_ps(_mm512_set1_epi32(-1)));
+ }
+ template <class A>
+ XSIMD_INLINE batch<double, A> bitwise_not(batch<double, A> const& self, requires_arch<avx512f>) noexcept
+ {
+ return _mm512_xor_pd(self, _mm512_castsi512_pd(_mm512_set1_epi32(-1)));
+ }
+
+ // bitwise_or
+ template <class A>
+ XSIMD_INLINE batch<float, A> bitwise_or(batch<float, A> const& self, batch<float, A> const& other, requires_arch<avx512dq>) noexcept
+ {
+ return _mm512_or_ps(self, other);
+ }
+ template <class A>
+ XSIMD_INLINE batch<double, A> bitwise_or(batch<double, A> const& self, batch<double, A> const& other, requires_arch<avx512dq>) noexcept
+ {
+ return _mm512_or_pd(self, other);
+ }
+
+ template <class A, class T>
+ XSIMD_INLINE batch_bool<T, A> bitwise_or(batch_bool<T, A> const& self, batch_bool<T, A> const& other, requires_arch<avx512dq>) noexcept
+ {
+ using register_type = typename batch_bool<T, A>::register_type;
+ return register_type(self.data | other.data);
+ }
+
+ // bitwise_xor
+ template <class A>
+ XSIMD_INLINE batch<float, A> bitwise_xor(batch<float, A> const& self, batch<float, A> const& other, requires_arch<avx512dq>) noexcept
+ {
+ return _mm512_xor_ps(self, other);
+ }
+ template <class A>
+ XSIMD_INLINE batch<double, A> bitwise_xor(batch<double, A> const& self, batch<double, A> const& other, requires_arch<avx512dq>) noexcept
+ {
+ return _mm512_xor_pd(self, other);
+ }
+
+ // haddp
+ template <class A>
+ XSIMD_INLINE batch<float, A> haddp(batch<float, A> const* row, requires_arch<avx512dq>) noexcept
+ {
+ // The following folds over the vector once:
+ // tmp1 = [a0..8, b0..8]
+ // tmp2 = [a8..f, b8..f]
+#define XSIMD_AVX512_HADDP_STEP1(I, a, b) \
+ batch<float, avx512f> res##I; \
+ { \
+ auto tmp1 = _mm512_shuffle_f32x4(a, b, _MM_SHUFFLE(1, 0, 1, 0)); \
+ auto tmp2 = _mm512_shuffle_f32x4(a, b, _MM_SHUFFLE(3, 2, 3, 2)); \
+ res##I = _mm512_add_ps(tmp1, tmp2); \
+ }
+
+ XSIMD_AVX512_HADDP_STEP1(0, row[0], row[2]);
+ XSIMD_AVX512_HADDP_STEP1(1, row[4], row[6]);
+ XSIMD_AVX512_HADDP_STEP1(2, row[1], row[3]);
+ XSIMD_AVX512_HADDP_STEP1(3, row[5], row[7]);
+ XSIMD_AVX512_HADDP_STEP1(4, row[8], row[10]);
+ XSIMD_AVX512_HADDP_STEP1(5, row[12], row[14]);
+ XSIMD_AVX512_HADDP_STEP1(6, row[9], row[11]);
+ XSIMD_AVX512_HADDP_STEP1(7, row[13], row[15]);
+
+#undef XSIMD_AVX512_HADDP_STEP1
+
+ // The following flds the code and shuffles so that hadd_ps produces the correct result
+ // tmp1 = [a0..4, a8..12, b0..4, b8..12] (same for tmp3)
+ // tmp2 = [a5..8, a12..16, b5..8, b12..16] (same for tmp4)
+ // tmp5 = [r1[0], r1[2], r2[0], r2[2], r1[4], r1[6] ...
+#define XSIMD_AVX512_HADDP_STEP2(I, a, b, c, d) \
+ batch<float, avx2> halfx##I; \
+ { \
+ auto tmp1 = _mm512_shuffle_f32x4(a, b, _MM_SHUFFLE(2, 0, 2, 0)); \
+ auto tmp2 = _mm512_shuffle_f32x4(a, b, _MM_SHUFFLE(3, 1, 3, 1)); \
+ \
+ auto resx1 = _mm512_add_ps(tmp1, tmp2); \
+ \
+ auto tmp3 = _mm512_shuffle_f32x4(c, d, _MM_SHUFFLE(2, 0, 2, 0)); \
+ auto tmp4 = _mm512_shuffle_f32x4(c, d, _MM_SHUFFLE(3, 1, 3, 1)); \
+ \
+ auto resx2 = _mm512_add_ps(tmp3, tmp4); \
+ \
+ auto tmp5 = _mm512_shuffle_ps(resx1, resx2, _MM_SHUFFLE(2, 0, 2, 0)); \
+ auto tmp6 = _mm512_shuffle_ps(resx1, resx2, _MM_SHUFFLE(3, 1, 3, 1)); \
+ \
+ auto resx3 = _mm512_add_ps(tmp5, tmp6); \
+ \
+ halfx##I = _mm256_hadd_ps(_mm512_extractf32x8_ps(resx3, 0), \
+ _mm512_extractf32x8_ps(resx3, 1)); \
+ }
+
+ XSIMD_AVX512_HADDP_STEP2(0, res0, res1, res2, res3);
+ XSIMD_AVX512_HADDP_STEP2(1, res4, res5, res6, res7);
+
+#undef XSIMD_AVX512_HADDP_STEP2
+
+ auto concat = _mm512_castps256_ps512(halfx0);
+ concat = _mm512_insertf32x8(concat, halfx1, 1);
+ return concat;
+ }
+
+ // ldexp
+ template <class A>
+ XSIMD_INLINE batch<double, A> ldexp(const batch<double, A>& self, const batch<as_integer_t<double>, A>& other, requires_arch<avx512dq>) noexcept
+ {
+ return _mm512_scalef_pd(self, _mm512_cvtepi64_pd(other));
+ }
+
+ // mul
+ template <class A>
+ XSIMD_INLINE batch<uint64_t, A> mul(batch<uint64_t, A> const& self, batch<uint64_t, A> const& other, requires_arch<avx512dq>) noexcept
+ {
+ return _mm512_mullo_epi64(self, other);
+ }
+
+ template <class A>
+ XSIMD_INLINE batch<int64_t, A> mul(batch<int64_t, A> const& self, batch<int64_t, A> const& other, requires_arch<avx512dq>) noexcept
+ {
+ return _mm512_mullo_epi64(self, other);
+ }
+
+ // nearbyint_as_int
+ template <class A>
+ XSIMD_INLINE batch<int64_t, A> nearbyint_as_int(batch<double, A> const& self,
+ requires_arch<avx512dq>) noexcept
+ {
+ return _mm512_cvtpd_epi64(self);
+ }
+
+ // reduce_add
+ template <class A>
+ XSIMD_INLINE float reduce_add(batch<float, A> const& rhs, requires_arch<avx512f>) noexcept
+ {
+ __m256 tmp1 = _mm512_extractf32x8_ps(rhs, 1);
+ __m256 tmp2 = _mm512_extractf32x8_ps(rhs, 0);
+ __m256 res1 = _mm256_add_ps(tmp1, tmp2);
+ return reduce_add(batch<float, avx2>(res1), avx2 {});
+ }
+
+ // convert
+ namespace detail
+ {
+ template <class A>
+ XSIMD_INLINE batch<double, A> fast_cast(batch<int64_t, A> const& x, batch<double, A> const&, requires_arch<avx512dq>) noexcept
+ {
+ return _mm512_cvtepi64_pd(self);
+ }
+
+ template <class A>
+ XSIMD_INLINE batch<int64_t, A> fast_cast(batch<double, A> const& self, batch<int64_t, A> const&, requires_arch<avx512dq>) noexcept
+ {
+ return _mm512_cvttpd_epi64(self);
+ }
+
+ }
+
+ }
+
+}
+
+#endif