-----------------------------------------------------------------------------
-- |
-- Module      : Data.Array.Parallel.Unlifted.Sequential.Segmented.Basics
-- Copyright   : (c) [2001..2002] Manuel M T Chakravarty & Gabriele Keller
--		 (c) 2006         Manuel M T Chakravarty & Roman Leshchinskiy
-- License     : see libraries/ndp/LICENSE
-- 
-- Maintainer  : Roman Leshchinskiy <rl@cse.unsw.edu.au>
-- Stability   : internal
-- Portability : portable
--
-- Description ---------------------------------------------------------------
--
--  Subarray operations on unlifted segmented arrays.
--
-- Todo ----------------------------------------------------------------------
--

module Data.Array.Parallel.Unlifted.Sequential.Segmented.Subarrays (
  sliceSU, extractSU, takeCU, dropCU
) where

import Data.Array.Parallel.Unlifted.Sequential.Flat (
  UA, (!:), sliceU, extractU, lengthU)
import Data.Array.Parallel.Unlifted.Sequential.Segmented.SUArr (
  SUArr, sliceUSegd, extractUSegd, (>:), segdSU, lengthSU, indicesSU)
import Data.Array.Parallel.Unlifted.Sequential.Segmented.Basics (
  concatSU)

-- |Extract a subrange of the segmented array without copying the elements.
--
sliceSU :: UA e => SUArr e -> Int -> Int -> SUArr e
sliceSU sa i n =
  let
    a     = concatSU sa
    i'    = indicesSU sa !: i
    j     = if i+n == lengthSU sa then lengthU a else indicesSU sa !: (i+n)
  in
  sliceUSegd (segdSU sa) i n >: sliceU a i' j
    
-- |Extract a subrange of the segmented array (elements are copied).
--
extractSU :: UA e => SUArr e -> Int -> Int -> SUArr e
extractSU sa i n =
  let
    a     = concatSU sa
    i'    = indicesSU sa !: i
    j     = if i+n == lengthSU sa then lengthU a else indicesSU sa !: (i+n)
  in
  extractUSegd (segdSU sa) i n >: extractU a i' j


takeCU:: (UA e) => Int ->  SUArr e  -> SUArr e
{-# INLINE takeCU #-}
takeCU n xssArr = sliceSU xssArr 0 n 



dropCU:: (UA e) => Int ->  SUArr e  -> SUArr e
{-# INLINE dropCU #-}
dropCU n xssArr = sliceSU xssArr n (lengthSU xssArr - n)