{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
-- |
-- Module      : Data.Massiv.Core.Index.Tuple
-- Copyright   : (c) Alexey Kuleshevich 2018-2021
-- License     : BSD3
-- Maintainer  : Alexey Kuleshevich <alexey@kuleshevi.ch>
-- Stability   : experimental
-- Portability : non-portable
--
module Data.Massiv.Core.Index.Tuple
  ( -- * Tuple based indices
    -- ** 1-dimensional
    Ix1T
    -- ** 2-dimensional
  , Ix2T
  , toIx2
  , fromIx2
    -- ** 3-dimensional
  , Ix3T
  , toIx3
  , fromIx3
    -- ** 4-dimensional
  , Ix4T
  , toIx4
  , fromIx4
    -- ** 5-dimensional
  , Ix5T
  , toIx5
  , fromIx5
  ) where

import Control.Monad.Catch (MonadThrow(..))
import Data.Massiv.Core.Index.Internal (Index(..), IndexException(..), Lower,
                                        Sz(..))
import Data.Massiv.Core.Index.Ix

-- | Another 1-dimensional index type synonym for `Int`, same as `Ix1` and is here just for
-- consistency.
type Ix1T = Int

-- | 2-dimensional index as tuple of `Int`s.
type Ix2T = (Int, Int)

-- | 3-dimensional index as 3-tuple of `Int`s.
type Ix3T = (Int, Int, Int)

-- | 4-dimensional index as 4-tuple of `Int`s.
type Ix4T = (Int, Int, Int, Int)

-- | 5-dimensional index as 5-tuple of `Int`s.
type Ix5T = (Int, Int, Int, Int, Int)

type instance Lower Ix2T = Ix1T
type instance Lower Ix3T = Ix2T
type instance Lower Ix4T = Ix3T
type instance Lower Ix5T = Ix4T



-- | Convert an `Int` tuple to `Ix2`
--
-- ==== __Example__
--
-- >>> toIx2 (2, 3)
-- 2 :. 3
--
-- @since 0.1.0
toIx2 :: Ix2T -> Ix2
toIx2 :: Ix2T -> Ix2
toIx2 (Int
i, Int
j) = Int
i Int -> Int -> Ix2
:. Int
j
{-# INLINE toIx2 #-}

-- | Convert an `Ix2` to `Int` tuple
--
-- ==== __Example__
--
-- >>> fromIx2 (2 :. 3)
-- (2,3)
--
-- @since 0.1.0
fromIx2 :: Ix2 -> Ix2T
fromIx2 :: Ix2 -> Ix2T
fromIx2 (Int
i :. Int
j) = (Int
i, Int
j)
{-# INLINE fromIx2 #-}

-- | Convert a `Int` 3-tuple to `Ix3`
--
-- ==== __Example__
--
-- >>> toIx3 (1, 2, 3)
-- 1 :> 2 :. 3
--
-- @since 0.1.0
toIx3 :: Ix3T -> Ix3
toIx3 :: Ix3T -> Ix3
toIx3 (Int
i, Int
j, Int
k) = Int
i Int -> Ix (3 - 1) -> Ix3
forall (n :: Nat). Int -> Ix (n - 1) -> IxN n
:> Int
j Int -> Int -> Ix2
:. Int
k
{-# INLINE toIx3 #-}

-- | Convert an `Ix3` to `Int` 3-tuple
--
-- ==== __Example__
--
-- >>> fromIx3 (1 :>  2 :. 3)
-- (1,2,3)
--
-- @since 0.1.0
fromIx3 :: Ix3 -> Ix3T
fromIx3 :: Ix3 -> Ix3T
fromIx3 (Int
i :> j :. k) = (Int
i, Int
j, Int
k)
{-# INLINE fromIx3 #-}

-- | Convert a `Int` 4-tuple to `Ix4`
--
-- ==== __Example__
--
-- >>> toIx4 (1, 2, 3, 4)
-- 1 :> 2 :> 3 :. 4
--
-- @since 0.1.0
toIx4 :: Ix4T -> Ix4
toIx4 :: Ix4T -> Ix4
toIx4 (Int
i, Int
j, Int
k, Int
l) = Int
i Int -> Ix (4 - 1) -> Ix4
forall (n :: Nat). Int -> Ix (n - 1) -> IxN n
:> Int
j Int -> Ix (3 - 1) -> Ix3
forall (n :: Nat). Int -> Ix (n - 1) -> IxN n
:> Int
k Int -> Int -> Ix2
:. Int
l
{-# INLINE toIx4 #-}

-- | Convert an `Ix4` to `Int` 4-tuple
--
-- ==== __Example__
--
-- >>> fromIx4 (1 :> 2 :> 3 :. 4)
-- (1,2,3,4)
--
-- @since 0.1.0
fromIx4 :: Ix4 -> Ix4T
fromIx4 :: Ix4 -> Ix4T
fromIx4 (Int
i :> j :> k :. l) = (Int
i, Int
j, Int
k, Int
l)
{-# INLINE fromIx4 #-}

-- | Convert a `Int` 5-tuple to `Ix5`
--
-- ==== __Example__
--
-- >>> toIx5 (1, 2, 3, 4, 5)
-- 1 :> 2 :> 3 :> 4 :. 5
--
-- @since 0.1.0
toIx5 :: Ix5T -> Ix5
toIx5 :: Ix5T -> Ix5
toIx5 (Int
i, Int
j, Int
k, Int
l, Int
m) = Int
i Int -> Ix (5 - 1) -> Ix5
forall (n :: Nat). Int -> Ix (n - 1) -> IxN n
:> Int
j Int -> Ix (4 - 1) -> Ix4
forall (n :: Nat). Int -> Ix (n - 1) -> IxN n
:> Int
k Int -> Ix (3 - 1) -> Ix3
forall (n :: Nat). Int -> Ix (n - 1) -> IxN n
:> Int
l Int -> Int -> Ix2
:. Int
m
{-# INLINE toIx5 #-}

-- | Convert an `Ix5` to `Int` 5-tuple
--
-- ==== __Example__
--
-- >>> fromIx5 (1 :> 2 :> 3 :> 4 :. 5)
-- (1,2,3,4,5)
--
-- @since 0.1.0
fromIx5 :: Ix5 -> Ix5T
fromIx5 :: Ix5 -> Ix5T
fromIx5 (Int
i :> j :> k :> l :. m) = (Int
i, Int
j, Int
k, Int
l, Int
m)
{-# INLINE fromIx5 #-}

-- |
-- @since 0.1.0
instance Index Ix2T where
  type Dimensions Ix2T = 2
  dimensions :: proxy Ix2T -> Dim
dimensions proxy Ix2T
_ = Dim
2
  {-# INLINE [1] dimensions #-}
  totalElem :: Sz Ix2T -> Int
totalElem (SafeSz (Int
k2, Int
k1)) = Int
k2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
k1
  {-# INLINE [1] totalElem #-}
  toLinearIndex :: Sz Ix2T -> Ix2T -> Int
toLinearIndex (SafeSz (Int
_, Int
k1)) (Int
i2, Int
i1) = Int
k1 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
i2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
i1
  {-# INLINE [1] toLinearIndex #-}
  fromLinearIndex :: Sz Ix2T -> Int -> Ix2T
fromLinearIndex (SafeSz (Int
_, Int
k1)) !Int
i = Int
i Int -> Int -> Ix2T
forall a. Integral a => a -> a -> (a, a)
`quotRem` Int
k1
  {-# INLINE [1] fromLinearIndex #-}
  consDim :: Int -> Lower Ix2T -> Ix2T
consDim = (,)
  {-# INLINE [1] consDim #-}
  unconsDim :: Ix2T -> (Int, Lower Ix2T)
unconsDim = Ix2T -> (Int, Lower Ix2T)
forall a. a -> a
id
  {-# INLINE [1] unconsDim #-}
  snocDim :: Lower Ix2T -> Int -> Ix2T
snocDim = (,)
  {-# INLINE [1] snocDim #-}
  unsnocDim :: Ix2T -> (Lower Ix2T, Int)
unsnocDim = Ix2T -> (Lower Ix2T, Int)
forall a. a -> a
id
  {-# INLINE [1] unsnocDim #-}
  getDimM :: Ix2T -> Dim -> m Int
getDimM (Int
i2,  Int
_) Dim
2 = Int -> m Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
i2
  getDimM ( Int
_, Int
i1) Dim
1 = Int -> m Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
i1
  getDimM Ix2T
ix       Dim
d = IndexException -> m Int
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (IndexException -> m Int) -> IndexException -> m Int
forall a b. (a -> b) -> a -> b
$ Ix2T -> Dim -> IndexException
forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Ix2T
ix Dim
d
  {-# INLINE [1] getDimM #-}
  setDimM :: Ix2T -> Dim -> Int -> m Ix2T
setDimM (Int
_, Int
i1) Dim
2 Int
i2 = Ix2T -> m Ix2T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i2, Int
i1)
  setDimM (Int
i2, Int
_) Dim
1 Int
i1 = Ix2T -> m Ix2T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i2, Int
i1)
  setDimM Ix2T
ix      Dim
d Int
_  = IndexException -> m Ix2T
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (IndexException -> m Ix2T) -> IndexException -> m Ix2T
forall a b. (a -> b) -> a -> b
$ Ix2T -> Dim -> IndexException
forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Ix2T
ix Dim
d
  {-# INLINE [1] setDimM #-}
  modifyDimM :: Ix2T -> Dim -> (Int -> Int) -> m (Int, Ix2T)
modifyDimM (Int
i2, Int
i1) Dim
2 Int -> Int
f = (Int, Ix2T) -> m (Int, Ix2T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i2, (Int -> Int
f Int
i2,   Int
i1))
  modifyDimM (Int
i2, Int
i1) Dim
1 Int -> Int
f = (Int, Ix2T) -> m (Int, Ix2T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i1, (  Int
i2, Int -> Int
f Int
i1))
  modifyDimM Ix2T
ix       Dim
d Int -> Int
_  = IndexException -> m (Int, Ix2T)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (IndexException -> m (Int, Ix2T))
-> IndexException -> m (Int, Ix2T)
forall a b. (a -> b) -> a -> b
$ Ix2T -> Dim -> IndexException
forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Ix2T
ix Dim
d
  {-# INLINE [1] modifyDimM #-}
  pullOutDimM :: Ix2T -> Dim -> m (Int, Lower Ix2T)
pullOutDimM (Int
i2, Int
i1) Dim
2 = Ix2T -> m Ix2T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i2, Int
i1)
  pullOutDimM (Int
i2, Int
i1) Dim
1 = Ix2T -> m Ix2T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i1, Int
i2)
  pullOutDimM Ix2T
ix       Dim
d = IndexException -> m Ix2T
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (IndexException -> m Ix2T) -> IndexException -> m Ix2T
forall a b. (a -> b) -> a -> b
$ Ix2T -> Dim -> IndexException
forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Ix2T
ix Dim
d
  {-# INLINE [1] pullOutDimM #-}
  insertDimM :: Lower Ix2T -> Dim -> Int -> m Ix2T
insertDimM Lower Ix2T
i1 Dim
2 Int
i2 = Ix2T -> m Ix2T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i2, Int
Lower Ix2T
i1)
  insertDimM Lower Ix2T
i2 Dim
1 Int
i1 = Ix2T -> m Ix2T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
Lower Ix2T
i2, Int
i1)
  insertDimM Lower Ix2T
ix Dim
d  Int
_ = IndexException -> m Ix2T
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (IndexException -> m Ix2T) -> IndexException -> m Ix2T
forall a b. (a -> b) -> a -> b
$ Int -> Dim -> IndexException
forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Int
Lower Ix2T
ix Dim
d
  {-# INLINE [1] insertDimM #-}
  pureIndex :: Int -> Ix2T
pureIndex Int
i = (Int
i, Int
i)
  {-# INLINE [1] pureIndex #-}
  liftIndex2 :: (Int -> Int -> Int) -> Ix2T -> Ix2T -> Ix2T
liftIndex2 Int -> Int -> Int
f (Int
i2, Int
i1) (Int
i2', Int
i1') = (Int -> Int -> Int
f Int
i2 Int
i2', Int -> Int -> Int
f Int
i1 Int
i1')
  {-# INLINE [1] liftIndex2 #-}


-- |
-- @since 0.1.0
instance Index Ix3T where
  type Dimensions Ix3T = 3
  dimensions :: proxy Ix3T -> Dim
dimensions proxy Ix3T
_ = Dim
3
  {-# INLINE [1] dimensions #-}
  totalElem :: Sz Ix3T -> Int
totalElem  (SafeSz (Int
k3, Int
k2, Int
k1)) = Int
k3 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
k2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
k1
  {-# INLINE [1] totalElem #-}
  consDim :: Int -> Lower Ix3T -> Ix3T
consDim Int
i3 (i2, i1) = (Int
i3, Int
i2, Int
i1)
  {-# INLINE [1] consDim #-}
  unconsDim :: Ix3T -> (Int, Lower Ix3T)
unconsDim (Int
i3, Int
i2, Int
i1) = (Int
i3, (Int
i2, Int
i1))
  {-# INLINE [1] unconsDim #-}
  snocDim :: Lower Ix3T -> Int -> Ix3T
snocDim (i3, i2) Int
i1 = (Int
i3, Int
i2, Int
i1)
  {-# INLINE [1] snocDim #-}
  unsnocDim :: Ix3T -> (Lower Ix3T, Int)
unsnocDim (Int
i3, Int
i2, Int
i1) = ((Int
i3, Int
i2), Int
i1)
  {-# INLINE [1] unsnocDim #-}
  getDimM :: Ix3T -> Dim -> m Int
getDimM (Int
i3,  Int
_,  Int
_) Dim
3 = Int -> m Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
i3
  getDimM ( Int
_, Int
i2,  Int
_) Dim
2 = Int -> m Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
i2
  getDimM ( Int
_,  Int
_, Int
i1) Dim
1 = Int -> m Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
i1
  getDimM Ix3T
ix           Dim
d = IndexException -> m Int
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (IndexException -> m Int) -> IndexException -> m Int
forall a b. (a -> b) -> a -> b
$ Ix3T -> Dim -> IndexException
forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Ix3T
ix Dim
d
  {-# INLINE [1] getDimM #-}
  setDimM :: Ix3T -> Dim -> Int -> m Ix3T
setDimM ( Int
_, Int
i2, Int
i1) Dim
3 Int
i3 = Ix3T -> m Ix3T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i3, Int
i2, Int
i1)
  setDimM (Int
i3,  Int
_, Int
i1) Dim
2 Int
i2 = Ix3T -> m Ix3T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i3, Int
i2, Int
i1)
  setDimM (Int
i3, Int
i2,  Int
_) Dim
1 Int
i1 = Ix3T -> m Ix3T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i3, Int
i2, Int
i1)
  setDimM Ix3T
ix           Dim
d Int
_  = IndexException -> m Ix3T
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (IndexException -> m Ix3T) -> IndexException -> m Ix3T
forall a b. (a -> b) -> a -> b
$ Ix3T -> Dim -> IndexException
forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Ix3T
ix Dim
d
  {-# INLINE [1] setDimM #-}
  modifyDimM :: Ix3T -> Dim -> (Int -> Int) -> m (Int, Ix3T)
modifyDimM (Int
i3, Int
i2, Int
i1) Dim
3 Int -> Int
f = (Int, Ix3T) -> m (Int, Ix3T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i3, (Int -> Int
f Int
i3,   Int
i2,   Int
i1))
  modifyDimM (Int
i3, Int
i2, Int
i1) Dim
2 Int -> Int
f = (Int, Ix3T) -> m (Int, Ix3T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i2, (  Int
i3, Int -> Int
f Int
i2,   Int
i1))
  modifyDimM (Int
i3, Int
i2, Int
i1) Dim
1 Int -> Int
f = (Int, Ix3T) -> m (Int, Ix3T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i1, (  Int
i3,   Int
i2, Int -> Int
f Int
i1))
  modifyDimM Ix3T
ix           Dim
d Int -> Int
_  = IndexException -> m (Int, Ix3T)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (IndexException -> m (Int, Ix3T))
-> IndexException -> m (Int, Ix3T)
forall a b. (a -> b) -> a -> b
$ Ix3T -> Dim -> IndexException
forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Ix3T
ix Dim
d
  {-# INLINE [1] modifyDimM #-}
  pullOutDimM :: Ix3T -> Dim -> m (Int, Lower Ix3T)
pullOutDimM (Int
i3, Int
i2, Int
i1) Dim
3 = (Int, Ix2T) -> m (Int, Ix2T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i3, (Int
i2, Int
i1))
  pullOutDimM (Int
i3, Int
i2, Int
i1) Dim
2 = (Int, Ix2T) -> m (Int, Ix2T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i2, (Int
i3, Int
i1))
  pullOutDimM (Int
i3, Int
i2, Int
i1) Dim
1 = (Int, Ix2T) -> m (Int, Ix2T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i1, (Int
i3, Int
i2))
  pullOutDimM Ix3T
ix           Dim
d = IndexException -> m (Int, Ix2T)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (IndexException -> m (Int, Ix2T))
-> IndexException -> m (Int, Ix2T)
forall a b. (a -> b) -> a -> b
$ Ix3T -> Dim -> IndexException
forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Ix3T
ix Dim
d
  {-# INLINE [1] pullOutDimM #-}
  insertDimM :: Lower Ix3T -> Dim -> Int -> m Ix3T
insertDimM (i2, i1) Dim
3 Int
i3 = Ix3T -> m Ix3T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i3, Int
i2, Int
i1)
  insertDimM (i3, i1) Dim
2 Int
i2 = Ix3T -> m Ix3T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i3, Int
i2, Int
i1)
  insertDimM (i3, i2) Dim
1 Int
i1 = Ix3T -> m Ix3T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i3, Int
i2, Int
i1)
  insertDimM Lower Ix3T
ix       Dim
d Int
_  = IndexException -> m Ix3T
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (IndexException -> m Ix3T) -> IndexException -> m Ix3T
forall a b. (a -> b) -> a -> b
$ Ix2T -> Dim -> IndexException
forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Ix2T
Lower Ix3T
ix Dim
d
  pureIndex :: Int -> Ix3T
pureIndex Int
i = (Int
i, Int
i, Int
i)
  {-# INLINE [1] pureIndex #-}
  liftIndex2 :: (Int -> Int -> Int) -> Ix3T -> Ix3T -> Ix3T
liftIndex2 Int -> Int -> Int
f (Int
i3, Int
i2, Int
i1) (Int
i3', Int
i2', Int
i1') = (Int -> Int -> Int
f Int
i3 Int
i3', Int -> Int -> Int
f Int
i2 Int
i2', Int -> Int -> Int
f Int
i1 Int
i1')
  {-# INLINE [1] liftIndex2 #-}


instance Index Ix4T where
  type Dimensions Ix4T = 4
  dimensions :: proxy Ix4T -> Dim
dimensions proxy Ix4T
_ = Dim
4
  {-# INLINE [1] dimensions #-}
  totalElem :: Sz Ix4T -> Int
totalElem (SafeSz (Int
k4, Int
k3, Int
k2, Int
k1)) = Int
k4 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
k3 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
k2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
k1
  {-# INLINE [1] totalElem #-}
  consDim :: Int -> Lower Ix4T -> Ix4T
consDim Int
i4 (i3, i2, i1) = (Int
i4, Int
i3, Int
i2, Int
i1)
  {-# INLINE [1] consDim #-}
  unconsDim :: Ix4T -> (Int, Lower Ix4T)
unconsDim (Int
i4, Int
i3, Int
i2, Int
i1) = (Int
i4, (Int
i3, Int
i2, Int
i1))
  {-# INLINE [1] unconsDim #-}
  snocDim :: Lower Ix4T -> Int -> Ix4T
snocDim (i4, i3, i2) Int
i1 = (Int
i4, Int
i3, Int
i2, Int
i1)
  {-# INLINE [1] snocDim #-}
  unsnocDim :: Ix4T -> (Lower Ix4T, Int)
unsnocDim (Int
i4, Int
i3, Int
i2, Int
i1) = ((Int
i4, Int
i3, Int
i2), Int
i1)
  {-# INLINE [1] unsnocDim #-}
  getDimM :: Ix4T -> Dim -> m Int
getDimM (Int
i4,  Int
_,  Int
_,  Int
_) Dim
4 = Int -> m Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
i4
  getDimM ( Int
_, Int
i3,  Int
_,  Int
_) Dim
3 = Int -> m Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
i3
  getDimM ( Int
_,  Int
_, Int
i2,  Int
_) Dim
2 = Int -> m Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
i2
  getDimM ( Int
_,  Int
_,  Int
_, Int
i1) Dim
1 = Int -> m Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
i1
  getDimM Ix4T
ix               Dim
d = IndexException -> m Int
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (IndexException -> m Int) -> IndexException -> m Int
forall a b. (a -> b) -> a -> b
$ Ix4T -> Dim -> IndexException
forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Ix4T
ix Dim
d
  {-# INLINE [1] getDimM #-}
  setDimM :: Ix4T -> Dim -> Int -> m Ix4T
setDimM ( Int
_, Int
i3, Int
i2, Int
i1) Dim
4 Int
i4 = Ix4T -> m Ix4T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i4, Int
i3, Int
i2, Int
i1)
  setDimM (Int
i4,  Int
_, Int
i2, Int
i1) Dim
3 Int
i3 = Ix4T -> m Ix4T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i4, Int
i3, Int
i2, Int
i1)
  setDimM (Int
i4, Int
i3,  Int
_, Int
i1) Dim
2 Int
i2 = Ix4T -> m Ix4T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i4, Int
i3, Int
i2, Int
i1)
  setDimM (Int
i4, Int
i3, Int
i2,  Int
_) Dim
1 Int
i1 = Ix4T -> m Ix4T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i4, Int
i3, Int
i2, Int
i1)
  setDimM Ix4T
ix               Dim
d  Int
_ = IndexException -> m Ix4T
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (IndexException -> m Ix4T) -> IndexException -> m Ix4T
forall a b. (a -> b) -> a -> b
$ Ix4T -> Dim -> IndexException
forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Ix4T
ix Dim
d
  {-# INLINE [1] setDimM #-}
  modifyDimM :: Ix4T -> Dim -> (Int -> Int) -> m (Int, Ix4T)
modifyDimM (Int
i4, Int
i3, Int
i2, Int
i1) Dim
4 Int -> Int
f = (Int, Ix4T) -> m (Int, Ix4T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i4, (Int -> Int
f Int
i4,   Int
i3,   Int
i2,   Int
i1))
  modifyDimM (Int
i4, Int
i3, Int
i2, Int
i1) Dim
3 Int -> Int
f = (Int, Ix4T) -> m (Int, Ix4T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i3, (  Int
i4, Int -> Int
f Int
i3,   Int
i2,   Int
i1))
  modifyDimM (Int
i4, Int
i3, Int
i2, Int
i1) Dim
2 Int -> Int
f = (Int, Ix4T) -> m (Int, Ix4T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i2, (  Int
i4,   Int
i3, Int -> Int
f Int
i2,   Int
i1))
  modifyDimM (Int
i4, Int
i3, Int
i2, Int
i1) Dim
1 Int -> Int
f = (Int, Ix4T) -> m (Int, Ix4T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i1, (  Int
i4,   Int
i3,   Int
i2, Int -> Int
f Int
i1))
  modifyDimM Ix4T
ix               Dim
d Int -> Int
_ = IndexException -> m (Int, Ix4T)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (IndexException -> m (Int, Ix4T))
-> IndexException -> m (Int, Ix4T)
forall a b. (a -> b) -> a -> b
$ Ix4T -> Dim -> IndexException
forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Ix4T
ix Dim
d
  {-# INLINE [1] modifyDimM #-}
  pullOutDimM :: Ix4T -> Dim -> m (Int, Lower Ix4T)
pullOutDimM (Int
i4, Int
i3, Int
i2, Int
i1) Dim
4 = (Int, Ix3T) -> m (Int, Ix3T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i4, (Int
i3, Int
i2, Int
i1))
  pullOutDimM (Int
i4, Int
i3, Int
i2, Int
i1) Dim
3 = (Int, Ix3T) -> m (Int, Ix3T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i3, (Int
i4, Int
i2, Int
i1))
  pullOutDimM (Int
i4, Int
i3, Int
i2, Int
i1) Dim
2 = (Int, Ix3T) -> m (Int, Ix3T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i2, (Int
i4, Int
i3, Int
i1))
  pullOutDimM (Int
i4, Int
i3, Int
i2, Int
i1) Dim
1 = (Int, Ix3T) -> m (Int, Ix3T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i1, (Int
i4, Int
i3, Int
i2))
  pullOutDimM Ix4T
ix               Dim
d = IndexException -> m (Int, Ix3T)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (IndexException -> m (Int, Ix3T))
-> IndexException -> m (Int, Ix3T)
forall a b. (a -> b) -> a -> b
$ Ix4T -> Dim -> IndexException
forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Ix4T
ix Dim
d
  {-# INLINE [1] pullOutDimM #-}
  insertDimM :: Lower Ix4T -> Dim -> Int -> m Ix4T
insertDimM (i3, i2, i1) Dim
4 Int
i4 = Ix4T -> m Ix4T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i4, Int
i3, Int
i2, Int
i1)
  insertDimM (i4, i2, i1) Dim
3 Int
i3 = Ix4T -> m Ix4T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i4, Int
i3, Int
i2, Int
i1)
  insertDimM (i4, i3, i1) Dim
2 Int
i2 = Ix4T -> m Ix4T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i4, Int
i3, Int
i2, Int
i1)
  insertDimM (i4, i3, i2) Dim
1 Int
i1 = Ix4T -> m Ix4T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i4, Int
i3, Int
i2, Int
i1)
  insertDimM Lower Ix4T
ix           Dim
d  Int
_ = IndexException -> m Ix4T
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (IndexException -> m Ix4T) -> IndexException -> m Ix4T
forall a b. (a -> b) -> a -> b
$ Ix3T -> Dim -> IndexException
forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Ix3T
Lower Ix4T
ix Dim
d
  {-# INLINE [1] insertDimM #-}
  pureIndex :: Int -> Ix4T
pureIndex Int
i = (Int
i, Int
i, Int
i, Int
i)
  {-# INLINE [1] pureIndex #-}
  liftIndex2 :: (Int -> Int -> Int) -> Ix4T -> Ix4T -> Ix4T
liftIndex2 Int -> Int -> Int
f (Int
i4, Int
i3, Int
i2, Int
i1) (Int
i4', Int
i3', Int
i2', Int
i1') = (Int -> Int -> Int
f Int
i4 Int
i4', Int -> Int -> Int
f Int
i3 Int
i3', Int -> Int -> Int
f Int
i2 Int
i2', Int -> Int -> Int
f Int
i1 Int
i1')
  {-# INLINE [1] liftIndex2 #-}


instance Index Ix5T where
  type Dimensions Ix5T = 5
  dimensions :: proxy Ix5T -> Dim
dimensions proxy Ix5T
_ = Dim
5
  {-# INLINE [1] dimensions #-}
  totalElem :: Sz Ix5T -> Int
totalElem (SafeSz (Int
n5, Int
n4, Int
n3, Int
n2, Int
n1)) = Int
n5 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
n4 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
n3 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
n2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
n1
  {-# INLINE [1] totalElem #-}
  consDim :: Int -> Lower Ix5T -> Ix5T
consDim Int
i5 (i4, i3, i2, i1) = (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1)
  {-# INLINE [1] consDim #-}
  unconsDim :: Ix5T -> (Int, Lower Ix5T)
unconsDim (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1) = (Int
i5, (Int
i4, Int
i3, Int
i2, Int
i1))
  {-# INLINE [1] unconsDim #-}
  snocDim :: Lower Ix5T -> Int -> Ix5T
snocDim (i5, i4, i3, i2) Int
i1 = (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1)
  {-# INLINE [1] snocDim #-}
  unsnocDim :: Ix5T -> (Lower Ix5T, Int)
unsnocDim (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1) = ((Int
i5, Int
i4, Int
i3, Int
i2), Int
i1)
  {-# INLINE [1] unsnocDim #-}
  getDimM :: Ix5T -> Dim -> m Int
getDimM (Int
i5,  Int
_,  Int
_,  Int
_,  Int
_) Dim
5 = Int -> m Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
i5
  getDimM ( Int
_, Int
i4,  Int
_,  Int
_,  Int
_) Dim
4 = Int -> m Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
i4
  getDimM ( Int
_,  Int
_, Int
i3,  Int
_,  Int
_) Dim
3 = Int -> m Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
i3
  getDimM ( Int
_,  Int
_,  Int
_, Int
i2,  Int
_) Dim
2 = Int -> m Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
i2
  getDimM ( Int
_,  Int
_,  Int
_,  Int
_, Int
i1) Dim
1 = Int -> m Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
i1
  getDimM Ix5T
ix                   Dim
d = IndexException -> m Int
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (IndexException -> m Int) -> IndexException -> m Int
forall a b. (a -> b) -> a -> b
$ Ix5T -> Dim -> IndexException
forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Ix5T
ix Dim
d
  {-# INLINE [1] getDimM #-}
  setDimM :: Ix5T -> Dim -> Int -> m Ix5T
setDimM ( Int
_, Int
i4, Int
i3, Int
i2, Int
i1) Dim
5 Int
i5 = Ix5T -> m Ix5T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1)
  setDimM (Int
i5,  Int
_, Int
i3, Int
i2, Int
i1) Dim
4 Int
i4 = Ix5T -> m Ix5T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1)
  setDimM (Int
i5, Int
i4,  Int
_, Int
i2, Int
i1) Dim
3 Int
i3 = Ix5T -> m Ix5T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1)
  setDimM (Int
i5, Int
i4, Int
i3,  Int
_, Int
i1) Dim
2 Int
i2 = Ix5T -> m Ix5T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1)
  setDimM (Int
i5, Int
i4, Int
i3, Int
i2,  Int
_) Dim
1 Int
i1 = Ix5T -> m Ix5T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1)
  setDimM Ix5T
ix                   Dim
d  Int
_ = IndexException -> m Ix5T
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (IndexException -> m Ix5T) -> IndexException -> m Ix5T
forall a b. (a -> b) -> a -> b
$ Ix5T -> Dim -> IndexException
forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Ix5T
ix Dim
d
  {-# INLINE [1] setDimM #-}
  modifyDimM :: Ix5T -> Dim -> (Int -> Int) -> m (Int, Ix5T)
modifyDimM (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1) Dim
5 Int -> Int
f = (Int, Ix5T) -> m (Int, Ix5T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i5, (Int -> Int
f Int
i5,   Int
i4,   Int
i3,   Int
i2,   Int
i1))
  modifyDimM (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1) Dim
4 Int -> Int
f = (Int, Ix5T) -> m (Int, Ix5T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i4, (  Int
i5, Int -> Int
f Int
i4,   Int
i3,   Int
i2,   Int
i1))
  modifyDimM (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1) Dim
3 Int -> Int
f = (Int, Ix5T) -> m (Int, Ix5T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i3, (  Int
i5,   Int
i4, Int -> Int
f Int
i3,   Int
i2,   Int
i1))
  modifyDimM (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1) Dim
2 Int -> Int
f = (Int, Ix5T) -> m (Int, Ix5T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i2, (  Int
i5,   Int
i4,   Int
i3, Int -> Int
f Int
i2,   Int
i1))
  modifyDimM (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1) Dim
1 Int -> Int
f = (Int, Ix5T) -> m (Int, Ix5T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i1, (  Int
i5,   Int
i4,   Int
i3,   Int
i2, Int -> Int
f Int
i1))
  modifyDimM Ix5T
ix                   Dim
d Int -> Int
_ = IndexException -> m (Int, Ix5T)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (IndexException -> m (Int, Ix5T))
-> IndexException -> m (Int, Ix5T)
forall a b. (a -> b) -> a -> b
$ Ix5T -> Dim -> IndexException
forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Ix5T
ix Dim
d
  {-# INLINE [1] modifyDimM #-}
  pullOutDimM :: Ix5T -> Dim -> m (Int, Lower Ix5T)
pullOutDimM (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1) Dim
5 = (Int, Ix4T) -> m (Int, Ix4T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i5, (Int
i4, Int
i3, Int
i2, Int
i1))
  pullOutDimM (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1) Dim
4 = (Int, Ix4T) -> m (Int, Ix4T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i4, (Int
i5, Int
i3, Int
i2, Int
i1))
  pullOutDimM (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1) Dim
3 = (Int, Ix4T) -> m (Int, Ix4T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i3, (Int
i5, Int
i4, Int
i2, Int
i1))
  pullOutDimM (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1) Dim
2 = (Int, Ix4T) -> m (Int, Ix4T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i2, (Int
i5, Int
i4, Int
i3, Int
i1))
  pullOutDimM (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1) Dim
1 = (Int, Ix4T) -> m (Int, Ix4T)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i1, (Int
i5, Int
i4, Int
i3, Int
i2))
  pullOutDimM Ix5T
ix                   Dim
d = IndexException -> m (Int, Ix4T)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (IndexException -> m (Int, Ix4T))
-> IndexException -> m (Int, Ix4T)
forall a b. (a -> b) -> a -> b
$ Ix5T -> Dim -> IndexException
forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Ix5T
ix Dim
d
  {-# INLINE [1] pullOutDimM #-}
  insertDimM :: Lower Ix5T -> Dim -> Int -> m Ix5T
insertDimM (i4, i3, i2, i1) Dim
5 Int
i5 = Ix5T -> m Ix5T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1)
  insertDimM (i5, i3, i2, i1) Dim
4 Int
i4 = Ix5T -> m Ix5T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1)
  insertDimM (i5, i4, i2, i1) Dim
3 Int
i3 = Ix5T -> m Ix5T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1)
  insertDimM (i5, i4, i3, i1) Dim
2 Int
i2 = Ix5T -> m Ix5T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1)
  insertDimM (i5, i4, i3, i2) Dim
1 Int
i1 = Ix5T -> m Ix5T
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1)
  insertDimM Lower Ix5T
ix               Dim
d  Int
_ = IndexException -> m Ix5T
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (IndexException -> m Ix5T) -> IndexException -> m Ix5T
forall a b. (a -> b) -> a -> b
$ Ix4T -> Dim -> IndexException
forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Ix4T
Lower Ix5T
ix Dim
d
  {-# INLINE [1] insertDimM #-}
  pureIndex :: Int -> Ix5T
pureIndex Int
i = (Int
i, Int
i, Int
i, Int
i, Int
i)
  {-# INLINE [1] pureIndex #-}
  liftIndex2 :: (Int -> Int -> Int) -> Ix5T -> Ix5T -> Ix5T
liftIndex2 Int -> Int -> Int
f (Int
i5, Int
i4, Int
i3, Int
i2, Int
i1) (Int
i5', Int
i4', Int
i3', Int
i2', Int
i1') =
    (Int -> Int -> Int
f Int
i5 Int
i5', Int -> Int -> Int
f Int
i4 Int
i4', Int -> Int -> Int
f Int
i3 Int
i3', Int -> Int -> Int
f Int
i2 Int
i2', Int -> Int -> Int
f Int
i1 Int
i1')
  {-# INLINE [1] liftIndex2 #-}