#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 PYTHONIC_NS_BEGIN namespace builtins { namespace details { template struct map_res { using type = decltype( std::declval()(std::declval::value_type>()...)); }; template struct map_res { using type = decltype(types::make_tuple(std::declval::value_type>()...)); }; template struct map_iterator : std::iterator< typename utils::iterator_min::type, typename map_res::type> { std::tuple it; Operator _op; map_iterator() = default; template map_iterator(Operator const &_op, std::tuple &_iters, utils::index_sequence); template map_iterator(itertools::npos, Operator const &_op, std::tuple &_iters, utils::index_sequence); typename map_res::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 long min_len(map_iterator const &other, utils::int_) const; long min_len(map_iterator const &other, utils::int_<0>) const; template bool equal(map_iterator const &other, utils::int_) const; bool equal(map_iterator const &other, utils::int_<0>) const; template void advance(long i, utils::int_); void advance(long i, utils::int_<0>); template void next(utils::index_sequence); template typename map_res::type get_value(utils::index_sequence, std::true_type) const; template typename map_res::type get_value(utils::index_sequence, std::false_type) const; }; template struct map : utils::iterator_reminder, map_iterator { using iterator = map_iterator; using value_type = typename iterator::value_type; using dtype = typename types::dtype_of::type; static constexpr long value = 1 + utils::nested_container_depth::value; iterator end_iter; map() = default; // Use an extra template to enable forwarding template map(Operator const &_op, Types &&... _iters); iterator &begin(); iterator const &begin() const; iterator const &end() const; }; } template auto map(Operator &&_op, Iter &&... iters) -> details::map< typename std::remove_cv< typename std::remove_reference::type>::type, typename types::iterator::type>::type>::type...>; DEFINE_FUNCTOR(pythonic::builtins, map); } namespace types { template struct len_of> { static constexpr long value = len_of::type>::type>::value; }; template struct len_of> { static constexpr long _head = len_of::type>::type>::value; static constexpr long _tail = len_of>::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 struct __combined> { using type = typename __combined::value_type>>::type; }; #endif