close(); return true; } elseif ($it instanceof Generator) { try { $it->throw(new StopException()); return true; } catch (StopException $e) { } } return false; } /** * retourner la première valeur du tableau, de l'itérateur ou de l'instance * de Traversable, ou $default si aucun élément n'est trouvé. */ static final function first($values, $default=null) { if ($values instanceof IteratorAggregate) $values = $values->getIterator(); if ($values instanceof Iterator) { try { $values->rewind(); $value = $values->valid()? $values->current(): $default; } finally { self::close($values); } } elseif (is_array($values) || $values instanceof Traversable) { $value = $default; foreach ($values as $value) { break; } } else { throw self::unexpected_type($values); } return $value; } /** * retourner la première clé du tableau, de l'itérateur ou de l'instance * de Traversable, ou $default si aucun élément n'est trouvé. */ static final function first_key($values, $default=null) { if ($values instanceof IteratorAggregate) $values = $values->getIterator(); if ($values instanceof Iterator) { try { $values->rewind(); $key = $values->valid()? $values->key(): $default; } finally { self::close($values); } } elseif (is_array($values) || $values instanceof Traversable) { $key = $default; foreach ($values as $key => $ignored) { break; } } else { throw self::unexpected_type($values); } return $key; } ############################################################################# # outils pour gérer de façon générique des instances de {@link Iterator} ou # des arrays /** * @param $it ?iterable|array * @return bool true si l'itérateur ou le tableau ont pu être réinitialisés */ static function rewind(&$it, ?Exception &$exception=null): bool { if ($it instanceof Iterator) { try { $exception = null; $it->rewind(); return true; } catch (Exception $e) { $exception = $e; } } elseif ($it !== null) { reset($it); return true; } return false; } /** * @param $it ?iterable|array */ static function valid($it): bool { if ($it instanceof Iterator) { return $it->valid(); } elseif ($it !== null) { return key($it) !== null; } else { return false; } } /** * @param $it ?iterable|array */ static function current($it, &$key=null) { if ($it instanceof Iterator) { $key = $it->key(); return $it->current(); } elseif ($it !== null) { $key = key($it); return current($it); } else { $key = null; return null; } } /** * @param $it ?iterable|array */ static function next(&$it, ?Exception &$exception=null): void { if ($it instanceof Iterator) { try { $exception = null; $it->next(); } catch (Exception $e) { $exception = $e; } } elseif ($it !== null) { next($it); } } /** * obtenir la valeur de retour si $it est un générateur terminé, ou null sinon */ static function get_return($it) { if ($it instanceof Generator) { try { return $it->getReturn(); } catch (Exception $e) { } } return null; } }