As a followup to **How to sort dynamically allocated wordlists -- Sorting 
UncheckedArray type**

(<https://forum.nim-lang.org/t/12312>):

I am trying to use **UncheckedArray** types to support dynamic runtime 
dimensionality for **arrays** to avoid the overhead of **seqs**.

How do I avoid the referenced runtime error below.?:

  * **-d:nimNoLentIterators** compile switch doesn't help :-(
  * naïvely using **ref var openArray[string]** just compile errors**


    
    
    import algorithm
    
    # Allocate a dynamic integer array of size n
    proc createUncheckedArray[T](n: int): ptr UncheckedArray[T] =
      cast[ptr UncheckedArray[T]](cast[pointer](alloc(n * sizeof(T))))
    
    # Syntactic sugar
    template withLength*(elements: untyped, length: int): untyped =
      toOpenArray(elements, 0, length - 1)
    
    proc init_0_to_len*(elements: var openArray[int]) =
      for i in 0 .. elements.high:
        elements[i] = i
    
    # Generate a reordering vector to be used to place elements of associated 
arrays in sorted order
    template newOrder*() {.dirty.} =
      var
        length = elements.len
        index = createUncheckedArray[int](length)
      
      init_0_to_len index.withLength length
      
      # When MAKE_FAIL enabled the following generates the runtime error:
      #
      # Error: 'elements' is of type <var openArray[string]> which cannot
      # be captured as it would violate memory safety...
      # using '-d:nimNoLentIterators' helps in some cases.
      # Consider using a <ref var openArray[string]> which can be captured.
      
      (index.with_length length).sort do (a, b: int) -> int:
        elements[a].cmp elements[b]
      
      echo "newOrder: ", index.withLength length
      discard index
    
    # Using hardwired dimensionality -- works fine
    proc newOrder1*[T](elements: array[4, T]) =
      newOrder
    
    # Same as above but want to accept variable length element array
    proc newOrder2*[T](elements: var openArray[T]) =
      neworder
    
    when isMainModule:
      const MAKE_FAIL = false
      
      var
        words = ["aaa", "ddd", "ccc", "bbb"]
        integers = [1, 4, 3, 2]
      
      stdout.write "neworder1 string:   "; newOrder1[string](words)
    
    
    Run

Reply via email to