Array & ArrayView
Int[] dynamicArrayOfIntegers- „Dynamic array“ with dynamic size
Int[] array = [0, 1, 2] array[0] = 0 array[1] = 0 array[2] = 0 array[3] = 0 // Runtime error, no compile time bounds check - “Make simple things simple”,
having a short and traditional syntax for dynamic arrays should encourage people to use it. T[] arris the short form ofcilia::Array<T> arr- Also
[T] arr, as in Swift or Rust, has some merits.
And[3 T] arrfor fixed sized arrays would be fine for me (I don’t like[T;3] arr), but I’ll stick with the more traditionalT[] arr(like C# and Java).
- Also
- The long form is called
Array<T>, not, becauseVector<T>- that’s the more traditional wording,
- by using the word “vector”, the purpose of this class is not immediately clear (especially not for users of many languages other than C++, not even C),
Vectorcould too easily collide with the mathematical vector (as used in linear algebra or geometry).
- “Raw” C/C++ arrays are handled with
T*instead. std::arrayis calledcilia::StaticArrayinstead.- In C/C++
T[]means “array of certain (inferred) size”,- but that can be replaced with
T*andT[N]. - Also see https://cplusplus.com/forum/beginner/267321/#msg1150228
- but that can be replaced with
- „Dynamic array“ with dynamic size
Int[3] arrayOfThreeIntegers
(instead ofin C/C++)Int arrayOfThreeIntegers[3]- „Static array“ with fixed size
Int[3] array = [0, 1, 2] array[0] = 0 array[1] = 0 array[2] = 0 array[3] = 0 // Compilation error, due to compile time bounds check arrayOfThreeIntegers.size()->3- realized as extension function
func<type T, Int N> T[N]::size() -> Int { return N }
- realized as extension function
- „Static array“ with fixed size
- Use
T+/UniquePtr<T>for “raw” C/C++ arrays of arbitrary size.
But array subscript withInt+is unsafe.-
Int+ array = new Int[3] // Array-to-pointer decay possible unsafe { array[0] = 0 array[1] = 0 array[2] = 0 array[3] = 0 // Undefined behaviour, no bounds check at all } - Using
Int*for arrays is possible but generally unsafe.-
Int+ uniquePtrToArray = new Int[3] // Array-to-pointer decay possible unsafe { Int* array = uniquePtrToArray.release() array[0] = 0 array[1] = 0 array[2] = 0 array[3] = 0 // Undefined behaviour, no bounds check at all delete[] array } -
unsafe { Int* array = reinterpretCastTo<Int*>(malloc(3 * sizeof(Int))) array[0] = 0 array[1] = 0 array[2] = 0 array[3] = 0 // Undefined behaviour, no bounds check at all free(array) }
-
- Actually this is how to handle pointer to array of
Int“properly”:Int[3]+ arrayPtr = new Int[3] (*arrayPtr)[0] = 0 (*arrayPtr)[1] = 0 (*arrayPtr)[2] = 0 (*arrayPtr)[3] = 0 // Compilation error, due to compile time bounds check- But raw pointer access is still
unsafe:unsafe { Int[3]* arrayPtr = (new Int[3]).release() (*arrayPtr)[0] = 0 (*arrayPtr)[1] = 0 (*arrayPtr)[2] = 0 (*arrayPtr)[3] = 0 // Compilation error, due to compile time bounds check delete[] arrayPtr }
- But raw pointer access is still
-
- Examples:
Int[] dynamicArrayOfIntInt[3] arrayOfThreeIntInt[3]& referenceToArrayOfThreeIntInt[3]* pointerToArrayOfThreeIntInt[3][]& referenceToDynamicArrayOfArrayOfThreeIntString*[] dynamicArrayOfPointersToString
ArrayViewAKA Slice AKA Subarrayvar subarray = array[1..2]var subarray = array[1..<3]- Incomplete ranges (need lower and/or upper bounds before use) are
typcally implemented as inline functions that determine the concrete bounds and then call
array[start..end](or one of the exclusive counterparts).var subarray = array[..2]var subarray = array[..]
- See Rust Slices
- Multidimensional array
- dynamic size
Int[,] dynamic2DArrayT[,] arrayis the short form ofcilia::MDArray<2, T> array
Int[,,] multidimensionalDynamicArrayT[,,] arrayis the short form ofcilia::MDArray<3, T> array
- and so on:
cilia::MDArray<N, T>
- static size
Int[3, 2, 200]- Multidimensional static array
Int[3, 2, 200] intArray3D intArray3D[2, 1, 199] = 1 cilia::StaticMDArray<Int, 3, 2, 200> intArray3D
- Multidimensional static array
- dynamic size
- Mixed forms of static and dynamic array
Int[3][,] dynamic2DArrayOfArrayOfThreeIntInt[3,4][] dynamicArrayOfThreeByFourArrayOfInt
Associative Array
- AKA Map (or Dictionary)
TValue[TKey]as short form ofMap<TKey, TValue>- e.g.
ContactInfo[String] contactInfoForIDas short form
ofMap<String, ContactInfo> contactInfoForID, - as in D.
- There is no difference between these two, but “OtherMap<String, ContactInfo> contactInfoForID” allows you to select other map variants (SortedMap, HashMap etc.) if necessary.
- e.g.
- “Make simple things simple”,
having a short syntax for associative arrays so they are easy to use. - Maybe partial template specialization:
Map<Int, ...>is aHashMapMap<String, ...>is aSortedMap