{-# LANGUAGE BangPatterns #-}
{- |
Module      :  $Header$
Description :  Encapsulation of start and end index of an array.
Copyright   :  (c) Alexandros Gremm
License     :  BSD3

Maintainer  :  agremm@posteo.de
Stability   :  experimental
Portability :  non-portable (GHC extensions)

  Encapsulation of start and end index of an array.
-}
module Data.Array.Matryoshka.Range (
  Range (Range),
  createRange,
  lengthRange,
  fstRange,
  sndRange,
  splitAtRange
  )
where

data Range = Range !Int !Int

lengthRange :: Range -> Int
{-# INLINABLE lengthRange #-}
lengthRange !(Range !s !e) = e - s

createRange :: Int -> Int -> Range
{-# INLINABLE createRange #-}
createRange !s !e = Range s e

fstRange :: Range -> Int
{-# INLINABLE fstRange #-}
fstRange (Range !s _) = s

sndRange :: Range -> Int
{-# INLINABLE sndRange #-}
sndRange (Range _ !e) = e

splitAtRange :: Int -> Range -> (Range, Range)
{-# INLINABLE splitAtRange #-}
splitAtRange !n !r@(Range !s !e) =
  let !len = lengthRange r
      !mini = min len n
      !cutOff = s + mini
      !lRange = createRange s cutOff
      !rRange = createRange cutOff e
      !res = (lRange, rRange)
  in res

