GSL : Bibliothèque de support des lignes directrices

La GSL est une petite bibliothèque de facilités conçue pour soutenir cet ensemble de lignes directrices.
Sans ces facilités, les lignes directrices devraient être bien plus restrictives sur les détails du langage.

La bibliothèque de support des lignes directrices se définit dans l’espace de noms gsl et les noms peuvent être des alias pour les noms de la bibliothèque standard ou d’autres bibliothèques bien connues. L’utilisation de l’indirection (temps de compilation) via l’espace de noms gsl permet l’expérimentation et des variantes locales des facilités de support.

La GSL est uniquement une bibliothèque d’en‑tête, et se trouve à l’adresse
GSL : Bibliothèque de support des lignes directrices.
Les facilités de la bibliothèque de support sont conçues pour être extrêmement légères (zéro‑surcoût) afin de ne pas imposer d’encombrement par rapport à l’utilisation d’alternatives conventionnelles.
Lorsqu’il est souhaité, elles peuvent être « instrumentées » avec des fonctionnalités supplémentaires (par ex., des vérifications) pour des tâches telles que le débogage.

Ces lignes directrices utilisent des types provenant de la bibliothèque standard (p. ex., C++17) en plus de ceux de la GSL.
Par ex., nous supposons un type variant, mais celui‑ci n’est pas encore présent dans la GSL.
À l’avenir, utilisez le type adopté dans C++17.

Certains types GSL listés ci‑dessous pourraient ne pas être pris en charge dans la bibliothèque que vous utilisez en raison de contraintes techniques telles que les limites des versions actuelles de C++.
Veuillez consulter la documentation de votre GSL pour en savoir plus.

Pour chaque type GSL ci‑dessous, nous énonçons un invariant pour ce type.
Cet invariant reste valable tant que le code utilisateur ne modifie que l’état d’un objet GSL en utilisant les fonctions membres ou libres fournies par ce type (c.-à-d. le code utilisateur ne contournent pas l’interface du type pour modifier la valeur/les bits de l’objet en violant une autre règle des lignes directrices).

Résumé des composants GSL :

Nous prévoyons une spécification semi‑formelle « ISO C++ standard style » de la GSL.

Nous nous appuyons sur la bibliothèque standard ISO C++ et espérons que certaines parties de la GSL seront intégrées dans la bibliothèque standard.

GSL.view : Vues

Ces types permettent à l’utilisateur de distinguer les pointeurs propriétaires et non‑propriétaires ainsi que les pointeurs vers un seul objet et ceux vers le premier élément d’une séquence.

Ces « vues » ne sont jamais propriétaires.

Les références ne sont jamais propriétaires (voir R.4). @TODO-LINK
Note : les références ont de nombreuses occasions de dépasser la durée de vie des objets auxquels elles se réfèrent (retourner une variable locale par référence, conserver une référence à un élément d’un vecteur et appeler push_back, lier à std::max(x, y + 1), etc.). Le profil de sécurité de durée de vie vise à résoudre ces problèmes, mais même ainsi owner<T&> n’a aucun sens et est découragé.

Les noms sont majoritairement de style ISO de la bibliothèque standard (minuscules et tiret bas) :

La notation « pointeur brut » (p. ex. int*) est supposée avoir son sens le plus commun ; c’est‑à‑dire qu’un pointeur pointe vers un objet, mais ne le possède pas.
Les propriétaires doivent être convertis en gestionnaires de ressources (p. ex., unique_ptr ou vector<T>) ou marqués owner<T*>.

owner est utilisé pour marquer les pointeurs propriétaires dans le code qui ne peut pas être mis à niveau vers des gestionnaires de ressources appropriés.
Les raisons sont :

Un owner<T> diffère d’un gestionnaire de ressources pour un T par le fait qu’il requiert toujours un delete.

Un owner<T> est supposé référencer un objet dans le tas (heap).

Si quelque chose ne doit pas être nullptr, précisez‑le :

Un span<T> fait référence à zéro ou plusieurs T mutables à moins que T ne soit un type const.
Tous les accès aux éléments du span, notamment via operator[], sont garantis d’être vérifiés par les limites par défaut.

Remarque : le span de la GSL (initialement appelé array_view) a été proposé pour être inclus dans la bibliothèque standard C++, et a été adopté (avec des modifications de son nom et de son interface) sauf que std::span ne fournit pas de vérification garantie des limites. Par conséquent, la GSL a changé le nom et l’interface de span pour suivre std::span et devrait être exactement le même que std::span, et la seule différence devrait être que gsl::span est totalement sûr aux limites par défaut.
Si la sûreté des limites pouvait affecter son interface, ces propositions de changement devraient être ramenées via le comité ISO C++ pour garder gsl::span compatible avec std::span.
Si une évolution future de std::span ajoute une vérification des limites, gsl::span peut être supprimé.

« L’arithmétique de pointeur » se fait de préférence dans les span.
Un char* qui pointe vers plus d’un char mais n’est pas une chaîne de caractères de style C (p. ex., un pointeur dans un tampon d’entrée) devrait être représenté par un span.

Logiquement, ces deux alias ne sont pas nécessaires, mais nous ne sommes pas toujours logiques, et ils rendent explicite la distinction entre un pointeur vers un seul char et un pointeur vers une chaîne de caractères de style C.
Une séquence de caractères qui n’est pas supposée être terminée par zéro devrait être un span<char>, ou s’il est impossible à cause de problèmes d’ABI un char*, plutôt qu’un zstring.

Utilisez not_null<zstring> pour les chaînes de caractères de style C qui ne peuvent pas être nullptr.
??? Est‑ce qu’on a besoin d’un nom pour not_null<zstring> ? Ou est‑ce son impopularité ?

GSL.owner : Pointeurs propriétaires

GSL.assert : Assertions

Ces assertions sont actuellement des macros (cahottes !) et doivent apparaître uniquement dans les définitions de fonction, en attendant les décisions du comité standard sur les contrats et la syntaxe d’assertion.
Consultez la proposition de contrat ; en utilisant la syntaxe d’attribut, par ex., Expects(p) deviendra [[expects: p]].

GSL.util : Utilitaires

GSL.concept : Concepts

Ces concepts (prédicats de type) sont empruntés à la bibliothèque Origin d’Andrew Sutton, la proposition Range, et l’TR de l’ISO WG21 Palo Alto. Beaucoup d’entre eux sont très similaires à ce qui est devenu partie du standard ISO C++ en C++20.

GSL.ptr : Concepts de pointeurs intelligents