La biblioteca tl-ranges de Sy Brand [1], distribuida bajo una licencia de dominio público, proporciona una excelente implementación de adaptadores de rangos que no llegaron a ser incluidos en C++20. Entre ellos destacaríamos (los elementos estandarizados en C++23 se indican con un asterisco):
C++ -> Fundamentos de Programación
C++23 - Generador síncrono std::generator
Como primer ejemplo, consideremos el siguiente generador de números enteros pertenecientes a la sucesión de Fibonacci, es decir, aquélla que comienza con los números 0 y 1 y para la que cada valor subsiguiente se calcula como suma de los dos elementos que lo preceden. Por sencillez, ignoraremos el inevitable desbordamiento de enteros para valores elevados de la sucesión [1]:
"Hello, world!" en C++23
- A nivel del núcleo del lenguaje: if consteval [1], deducción de this [2], atributos en expresiones lambda [3], atributo [[assume]] [4], auto(x) y auto{x} [5], directiva #warning [6].
- A nivel de la biblioteca estándar: nuevas vistas std::views [7], <expected> [8], operaciones monádicas para std::optional [9], vistas para arrays multidimensionales <mdspan> [10], adaptadores de contenedores asociativos <flat_map> y <flat_set> [11, 12], generadores síncronos std::generator como soporte para corrutinas [13], funciones de impresión std::print y std::println en <print> [14].
Mónadas para programadores en C++: std::optional (Parte I)
- Una colección Ob(C) de objetos.
- Una colección Hom(C) de flechas o morfismos que enlazan dichos objetos. Un morfismo f del objeto X al objeto Y se denota f: X → Y. El conjunto de morfismos entre los objetos X e Y se denota HomC(X, Y).
- Una operación binaria de composición de morfismos. La composición de f: X → Y con g: Y → Z se denota g ∘ f: X → Z.
- Asociatividad: Si f: A → B, g: B → C y h: C → D, entonces h ∘ (g ∘ f) = (h ∘ g) ∘ f.
- Para cada objeto X, existe un morfismo identidad idX: X → X que se comporta como elemento neutro bajo composición, i.e., para todo morfismo f: X → Y se cumple f ∘ idX = idY ∘ f = f. Se puede demostrar que idX es único para cada X.
C++23 - Vista chunk_by
Introducción
- std::views::adjacent, std::views::adjacent_transform
- std::views::cartesian_product
- std::views::chunk, std::views::chunk_by
- std::views::join_with
- std::views::repeat
- std::views::slide
- std::views::stride
- std::views::zip, std::views::zip_transform
La vista std::views::chunk_by, centro de atención de este post, agrupa elementos contiguos de un rango a través de un predicado binario. Así, dado un rango de partida R=[T] de elementos de tipo T y un predicado binario P, la vista devolverá un rango de rangos [[T]] donde cada subrango contiene elementos contiguos de R que cumplen la siguiente condición: para cada elemento ei en el subrango a excepción del primero, la evaluación del predicado para el elemento inmediatamente anterior ei-1 y ei es verdadera, i.e., P(ei-1,ei)=true [2, 3]. Es importante señalar que no se requiere que dicho predicado constituya una relación de equivalencia.
mdspan: Vistas de arrays multidimensionales
La propuesta de estandarización P0009 para C++23 [1], cuya implementación puede encontrarse en la referencia [2], permite la adecuada gestión en C++ moderno de vistas no-propietarias y potencialmente mutables de arrays multidimensionales. Estas vistas son una herramienta de enorme interés en campos tan diversos como la Física, la Matemática o la Ingeniería y constituyen la piedra angular en torno a la cual el comité ISO C++ pretende diseñar una biblioteca de álgebra lineal basada en BLAS [3].
Sea I un espacio de índices multidimensionales de rango R, definido como el producto cartesiano de intervalos semiabiertos [0, N0) ⨯ [0, N1) ⨯ ... ⨯ [0, NR-1), con Nk natural para cada k = 0, ..., R-1. Una vista no propietaria de un array multidimensional de extensión k-ésima igual a Nk asociará a cada R-tupla de índices de acceso i ∈ I una referencia a un elemento accesible a través de un rango contiguo de índices enteros.