Refactor the ndarray adaptor and expose the array flags

This uses a cleaner pattern in the C implementation, instead of computing all pointers by hand.
Regardless of `parent`, we will need or want other fields later. For example my .flat() optimization (I'm gonna submit a PR) adds a `nitems` field to store the total number of items (the size() of the array).