@@ -1955,52 +1955,25 @@ inline std::pair<decltype(internals::registered_types_py)::iterator, bool> all_t
19551955 return res;
19561956}
19571957
1958- /* There are a large number of apparently unused template arguments because
1959- * each combination requires a separate py::class_ registration.
1960- */
1961- template <typename Access, return_value_policy Policy, typename Iterator, typename Sentinel, typename ValueType, typename ... Extra>
1958+ template <typename Iterator, typename Sentinel, bool KeyIterator, return_value_policy Policy>
19621959struct iterator_state {
19631960 Iterator it;
19641961 Sentinel end;
19651962 bool first_or_done;
19661963};
19671964
1968- // Note: these helpers take the iterator by non-const reference because some
1969- // iterators in the wild can't be dereferenced when const.
1970- template <typename Iterator>
1971- struct iterator_access {
1972- using result_type = decltype ((*std::declval<Iterator>()));
1973- // NOLINTNEXTLINE(readability-const-return-type) // PR #3263
1974- result_type operator ()(Iterator &it) const {
1975- return *it;
1976- }
1977- };
1978-
1979- template <typename Iterator>
1980- struct iterator_key_access {
1981- using result_type = decltype (((*std::declval<Iterator>()).first));
1982- result_type operator ()(Iterator &it) const {
1983- return (*it).first ;
1984- }
1985- };
1986-
1987- template <typename Iterator>
1988- struct iterator_value_access {
1989- using result_type = decltype (((*std::declval<Iterator>()).second));
1990- result_type operator ()(Iterator &it) const {
1991- return (*it).second ;
1992- }
1993- };
1965+ PYBIND11_NAMESPACE_END (detail)
19941966
1995- template < typename Access,
1996- return_value_policy Policy ,
1967+ // / Makes a python iterator from a first and past-the-end C++ InputIterator.
1968+ template <return_value_policy Policy = return_value_policy::reference_internal ,
19971969 typename Iterator,
19981970 typename Sentinel,
1999- typename ValueType,
1971+ #ifndef DOXYGEN_SHOULD_SKIP_THIS // Issue in breathe 4.26.1
1972+ typename ValueType = decltype (*std::declval<Iterator>()),
1973+ #endif
20001974 typename ... Extra>
2001- iterator make_iterator_impl (Iterator first, Sentinel last, Extra &&... extra) {
2002- using state = detail::iterator_state<Access, Policy, Iterator, Sentinel, ValueType, Extra...>;
2003- // TODO: state captures only the types of Extra, not the values
1975+ iterator make_iterator (Iterator first, Sentinel last, Extra &&... extra) {
1976+ using state = detail::iterator_state<Iterator, Sentinel, false , Policy>;
20041977
20051978 if (!detail::get_type_info (typeid (state), false )) {
20061979 class_<state>(handle (), " iterator" , pybind11::module_local ())
@@ -2014,63 +1987,43 @@ iterator make_iterator_impl(Iterator first, Sentinel last, Extra &&... extra) {
20141987 s.first_or_done = true ;
20151988 throw stop_iteration ();
20161989 }
2017- return Access ()( s.it ) ;
1990+ return * s.it ;
20181991 // NOLINTNEXTLINE(readability-const-return-type) // PR #3263
20191992 }, std::forward<Extra>(extra)..., Policy);
20201993 }
20211994
20221995 return cast (state{first, last, true });
20231996}
20241997
2025- PYBIND11_NAMESPACE_END (detail)
2026-
2027- // / Makes a python iterator from a first and past-the-end C++ InputIterator.
2028- template <return_value_policy Policy = return_value_policy::reference_internal,
2029- typename Iterator,
2030- typename Sentinel,
2031- typename ValueType = typename detail::iterator_access<Iterator>::result_type,
2032- typename ... Extra>
2033- iterator make_iterator (Iterator first, Sentinel last, Extra &&... extra) {
2034- return detail::make_iterator_impl<
2035- detail::iterator_access<Iterator>,
2036- Policy,
2037- Iterator,
2038- Sentinel,
2039- ValueType,
2040- Extra...>(first, last, std::forward<Extra>(extra)...);
2041- }
2042-
2043- // / Makes a python iterator over the keys (`.first`) of a iterator over pairs from a
1998+ // / Makes an python iterator over the keys (`.first`) of a iterator over pairs from a
20441999// / first and past-the-end InputIterator.
20452000template <return_value_policy Policy = return_value_policy::reference_internal,
20462001 typename Iterator,
20472002 typename Sentinel,
2048- typename KeyType = typename detail::iterator_key_access<Iterator>::result_type,
2003+ #ifndef DOXYGEN_SHOULD_SKIP_THIS // Issue in breathe 4.26.1
2004+ typename KeyType = decltype ((*std::declval<Iterator>()).first ),
2005+ #endif
20492006 typename ... Extra>
20502007iterator make_key_iterator (Iterator first, Sentinel last, Extra &&...extra ) {
2051- return detail::make_iterator_impl<
2052- detail::iterator_key_access<Iterator>,
2053- Policy,
2054- Iterator,
2055- Sentinel,
2056- KeyType,
2057- Extra...>(first, last, std::forward<Extra>(extra)...);
2058- }
2008+ using state = detail::iterator_state<Iterator, Sentinel, true , Policy>;
20592009
2060- // / Makes a python iterator over the values (`.second`) of a iterator over pairs from a
2061- // / first and past-the-end InputIterator.
2062- template <return_value_policy Policy = return_value_policy::reference_internal,
2063- typename Iterator,
2064- typename Sentinel,
2065- typename ValueType = typename detail::iterator_value_access<Iterator>::result_type,
2066- typename ... Extra>
2067- iterator make_value_iterator (Iterator first, Sentinel last, Extra &&...extra ) {
2068- return detail::make_iterator_impl<
2069- detail::iterator_value_access<Iterator>,
2070- Policy, Iterator,
2071- Sentinel,
2072- ValueType,
2073- Extra...>(first, last, std::forward<Extra>(extra)...);
2010+ if (!detail::get_type_info (typeid (state), false )) {
2011+ class_<state>(handle (), " iterator" , pybind11::module_local ())
2012+ .def (" __iter__" , [](state &s) -> state& { return s; })
2013+ .def (" __next__" , [](state &s) -> detail::remove_cv_t <KeyType> {
2014+ if (!s.first_or_done )
2015+ ++s.it ;
2016+ else
2017+ s.first_or_done = false ;
2018+ if (s.it == s.end ) {
2019+ s.first_or_done = true ;
2020+ throw stop_iteration ();
2021+ }
2022+ return (*s.it ).first ;
2023+ }, std::forward<Extra>(extra)..., Policy);
2024+ }
2025+
2026+ return cast (state{first, last, true });
20742027}
20752028
20762029// / Makes an iterator over values of an stl container or other container supporting
@@ -2087,13 +2040,6 @@ template <return_value_policy Policy = return_value_policy::reference_internal,
20872040 return make_key_iterator<Policy>(std::begin (value), std::end (value), extra...);
20882041}
20892042
2090- // / Makes an iterator over the values (`.second`) of a stl map-like container supporting
2091- // / `std::begin()`/`std::end()`
2092- template <return_value_policy Policy = return_value_policy::reference_internal,
2093- typename Type, typename ... Extra> iterator make_value_iterator (Type &value, Extra&&... extra) {
2094- return make_value_iterator<Policy>(std::begin (value), std::end (value), extra...);
2095- }
2096-
20972043template <typename InputType, typename OutputType> void implicitly_convertible () {
20982044 struct set_flag {
20992045 bool &flag;
0 commit comments