<commit_before># Copyright (c) 2015 SnapDisco Pty Ltd, Australia.
# All rights reserved.
# 
# This source code is licensed under the terms of the MIT license
# found in the "LICENSE" file in the root directory of this source tree.

## Nim type definition and accessors for the Numpy C-API PyArrayObject type.
##
## Documentation here:
##  http://docs.scipy.org/doc/numpy/reference/c-api.types-and-structures.html#c.PyArray_Type
##  http://docs.scipy.org/doc/numpy/reference/c-api.types-and-structures.html#c.PyArrayObject
##  http://docs.scipy.org/doc/numpy/reference/c-api.array.html#array-structure-and-data-access
##
## Most of these functions are preceded by the prefix `PyArray_` in the C-API.
##
## Instead, we prefix PyArrayObject accessor & creation functions with `get`
## (in place of the `PyArray_` prefix).  For example: PyArray_NDIM -> getNDIM


import pymodpkg/ptrutils
import pymodpkg/private/nptypes
import pymodpkg/private/pyarraydescrtype


## Nim type definition of the PyArrayObject type:
##  http://docs.scipy.org/doc/numpy/reference/c-api.types-and-structures.html#c.PyArrayObject 
type PyArrayObject* {. importc: "PyArrayObject", header: "pymodpkg/private/numpyarrayobject.h", final .} = object


# http://nim-lang.org/system.html#csize
type npy_intp* = csize


type CArrayProxy*[T] = object
  ## An indexable object that can be passed around in place of a C array.
  ##
  ## If you have a pointer `p` that points to a C array of known length `n`,
  ## this type allows you to pass around your pointer and index it, as if you
  ## were indexing arrays in C -- but now with soft range checking!
  ##
  ## ("Soft range checking" == return 0 rather than raising an exception.)
  ##
  ## NOTE:  This type should only be used when it is meaningful to return 0
  ## rather than raising an exception if the index is out of bounds.
  ##
  ## Fun fact:  Quite some time after I first created this type, I discovered
  ## that the Numpy C-API has an identical, rarely-used type `PyArray_Dims`:
  ##  http://docs.scipy.org/doc/numpy/reference/c-api.types-and-structures.html#c.PyArray_Dims
  ## (where PyArray_Dims == CArrayProxy[npy_intp]), except that `Pyarray_Dims`
  ## is passed as a parameter BY ADDRESS (ie, by pointer) rather than by value.
  ##
  ## TODO:  Should I replace this type with a Nim version of `PyArray_Dims`?
  p: ptr T
  n: cint

proc getPtr*[T](ap: CArrayProxy[T]): ptr T {. inline .} =
  return ap.p

proc getLen*[T](ap: CArrayProxy[T]): cint {. inline .} =
  return ap.n


proc `[]`*[T](ap: CArrayProxy[T], idx: int): T {. inline .} =
  ## NOTE:  This type should only be used when it is meaningful to return 0
  ## rather than raising an exception if the index `idx` is out of bounds.
  if idx < 0:
    return 0.T
  elif idx >= ap.n:
    return 0.T
  else:
    return offset_ptr(ap.p, idx)[]


proc `$`*[T](ap: CArrayProxy[T]): seq[string] =
  # Use memory allocation (a `seq[T]` instance) for a string representation.
  #
  # Based upon the usage example at:
  #  http://nim-lang.org/docs/system.html#newSeq,seq[T],Natural
  let num_elems = ap.getLen
  newSeq(result, num_elems)
  for i in 0..<num_elems:
    result[i] = $(ap[i])


iterator items*[T](ap: CArrayProxy[T]): T =
  let p: ptr T = ap.getPtr
  let n: cint = ap.getLen
  var i: cint = 0
  while i < n:
    yield (offset_ptr(p, i)[])
    inc(i)


# These procs mimic the Array C API data-access macros:
#  http://docs.scipy.org/doc/numpy/reference/c-api.array.html#array-structure-and-data-access
# (but with the prefix "PyArray_" changed to the verb "get")

proc getNDIM*(arr: ptr PyArrayObject): cint {.
    importc: "PyArray_NDIM", header: "pymodpkg/private/numpyarrayobject.h", cdecl .}

proc getDIMS*(arr: ptr PyArrayObject): ptr npy_intp {.
    importc: "PyArray_DIMS", header: "pymodpkg/private/numpyarrayobject.h", cdecl .}

proc getSHAPE*(arr: ptr PyArrayObject): ptr npy_intp {.
    importc: "PyArray_SHAPE", header: "pymodpkg/private/numpyarrayobject.h", cdecl .}<commit_msg>Whoops, just found a bug where `$` for type `CArrayProxy[T]` was returning `seq[string]` rather than just `string`.<commit_after># Copyright (c) 2015 SnapDisco Pty Ltd, Australia.
# All rights reserved.
# 
# This source code is licensed under the terms of the MIT license
# found in the "LICENSE" file in the root directory of this source tree.

## Nim type definition and accessors for the Numpy C-API PyArrayObject type.
##
## Documentation here:
##  http://docs.scipy.org/doc/numpy/reference/c-api.types-and-structures.html#c.PyArray_Type
##  http://docs.scipy.org/doc/numpy/reference/c-api.types-and-structures.html#c.PyArrayObject
##  http://docs.scipy.org/doc/numpy/reference/c-api.array.html#array-structure-and-data-access
##
## Most of these functions are preceded by the prefix `PyArray_` in the C-API.
##
## Instead, we prefix PyArrayObject accessor & creation functions with `get`
## (in place of the `PyArray_` prefix).  For example: PyArray_NDIM -> getNDIM


import pymodpkg/ptrutils
import pymodpkg/private/nptypes
import pymodpkg/private/pyarraydescrtype


## Nim type definition of the PyArrayObject type:
##  http://docs.scipy.org/doc/numpy/reference/c-api.types-and-structures.html#c.PyArrayObject 
type PyArrayObject* {. importc: "PyArrayObject", header: "pymodpkg/private/numpyarrayobject.h", final .} = object


# http://nim-lang.org/system.html#csize
type npy_intp* = csize


type CArrayProxy*[T] = object
  ## An indexable object that can be passed around in place of a C array.
  ##
  ## If you have a pointer `p` that points to a C array of known length `n`,
  ## this type allows you to pass around your pointer and index it, as if you
  ## were indexing arrays in C -- but now with soft range checking!
  ##
  ## ("Soft range checking" == return 0 rather than raising an exception.)
  ##
  ## NOTE:  This type should only be used when it is meaningful to return 0
  ## rather than raising an exception if the index is out of bounds.
  ##
  ## Fun fact:  Quite some time after I first created this type, I discovered
  ## that the Numpy C-API has an identical, rarely-used type `PyArray_Dims`:
  ##  http://docs.scipy.org/doc/numpy/reference/c-api.types-and-structures.html#c.PyArray_Dims
  ## (where PyArray_Dims == CArrayProxy[npy_intp]), except that `Pyarray_Dims`
  ## is passed as a parameter BY ADDRESS (ie, by pointer) rather than by value.
  ##
  ## TODO:  Should I replace this type with a Nim version of `PyArray_Dims`?
  p: ptr T
  n: cint

proc getPtr*[T](ap: CArrayProxy[T]): ptr T {. inline .} =
  return ap.p

proc getLen*[T](ap: CArrayProxy[T]): cint {. inline .} =
  return ap.n


proc `[]`*[T](ap: CArrayProxy[T], idx: int): T {. inline .} =
  ## NOTE:  This type should only be used when it is meaningful to return 0
  ## rather than raising an exception if the index `idx` is out of bounds.
  if idx < 0:
    return 0.T
  elif idx >= ap.n:
    return 0.T
  else:
    return offset_ptr(ap.p, idx)[]


proc `$`*[T](ap: CArrayProxy[T]): string =
  # Use memory allocation (a `seq[T]` instance) for a string representation.
  #
  # Based upon the usage example at:
  #  http://nim-lang.org/docs/system.html#newSeq,seq[T],Natural
  let num_elems = ap.getLen
  var ss: seq[string]
  newSeq(ss, num_elems)
  for i in 0..<num_elems:
    ss[i] = $(ap[i])
  result = $ss


iterator items*[T](ap: CArrayProxy[T]): T =
  let p: ptr T = ap.getPtr
  let n: cint = ap.getLen
  var i: cint = 0
  while i < n:
    yield (offset_ptr(p, i)[])
    inc(i)


# These procs mimic the Array C API data-access macros:
#  http://docs.scipy.org/doc/numpy/reference/c-api.array.html#array-structure-and-data-access
# (but with the prefix "PyArray_" changed to the verb "get")

proc getNDIM*(arr: ptr PyArrayObject): cint {.
    importc: "PyArray_NDIM", header: "pymodpkg/private/numpyarrayobject.h", cdecl .}

proc getDIMS*(arr: ptr PyArrayObject): ptr npy_intp {.
    importc: "PyArray_DIMS", header: "pymodpkg/private/numpyarrayobject.h", cdecl .}

proc getSHAPE*(arr: ptr PyArrayObject): ptr npy_intp {.
    importc: "PyArray_SHAPE", header: "pymodpkg/private/numpyarrayobject.h", cdecl .}
{'fraction_non_alphanumeric': 0.12796442687747037, 'fraction_numerical': 0.0029644268774703555, 'mean_word_length': 3.8253873659117996, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2963176', 'n_tokens_mistral': 2883, 'n_tokens_neox': 2803, 'n_words': 894}