{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilyDependencies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}

-- |
-- Module      : Data.Massiv.Core.Index.Ix
-- Copyright   : (c) Alexey Kuleshevich 2018-2022
-- License     : BSD3
-- Maintainer  : Alexey Kuleshevich <lehins@yandex.ru>
-- Stability   : experimental
-- Portability : non-portable
module Data.Massiv.Core.Index.Ix (
  Ix,
  IxN ((:>)),
  type Sz,
  pattern Sz,
  type Ix1,
  pattern Ix1,
  pattern Sz1,
  type Ix2 (Ix2, (:.)),
  pattern Sz2,
  type Ix3,
  pattern Ix3,
  pattern Sz3,
  type Ix4,
  pattern Ix4,
  pattern Sz4,
  type Ix5,
  pattern Ix5,
  pattern Sz5,
  HighIxN,
) where

import Control.DeepSeq
import Control.Monad.Catch (MonadThrow (..))
import Data.Massiv.Core.Index.Internal
import Data.Massiv.Core.Loop
import Data.Proxy
import qualified Data.Vector.Generic as V
import qualified Data.Vector.Generic.Mutable as VM
import qualified Data.Vector.Unboxed as VU
import qualified GHC.Arr as I
import GHC.TypeLits
import System.Random.Stateful
#if !MIN_VERSION_base(4,11,0)
import Data.Semigroup
#endif

infixr 5 :>, :.

-- | 2-dimensional index. This is also a base index for higher dimensions.
--
-- @since 0.1.0
data Ix2 = {-# UNPACK #-} !Int :. {-# UNPACK #-} !Int

-- | 2-dimensional index constructor. Useful when infix notation is inconvenient. @(Ix2 i j) == (i :. j)@
--
-- @since 0.1.0
pattern Ix2 :: Int -> Int -> Ix2
pattern $bIx2 :: Ix1 -> Ix1 -> Ix2
$mIx2 :: forall {r}. Ix2 -> (Ix1 -> Ix1 -> r) -> ((# #) -> r) -> r
Ix2 i2 i1 = i2 :. i1

{-# COMPLETE Ix2 #-}

-- | 2-dimensional size constructor. @(Sz2 i j) == Sz (i :. j)@
--
-- @since 0.3.0
pattern Sz2 :: Int -> Int -> Sz Ix2
pattern $bSz2 :: Ix1 -> Ix1 -> Sz Ix2
$mSz2 :: forall {r}. Sz Ix2 -> (Ix1 -> Ix1 -> r) -> ((# #) -> r) -> r
Sz2 i2 i1 = Sz (i2 :. i1)

{-# COMPLETE Sz2 #-}

-- | 3-dimensional type synonym. Useful as a alternative to enabling @DataKinds@ and using type
-- level Nats.
--
-- @since 0.1.0
type Ix3 = IxN 3

-- | 3-dimensional index constructor. @(Ix3 i j k) == (i :> j :. k)@
--
-- @since 0.1.0
pattern Ix3 :: Int -> Int -> Int -> Ix3
pattern $bIx3 :: Ix1 -> Ix1 -> Ix1 -> IxN 3
$mIx3 :: forall {r}. IxN 3 -> (Ix1 -> Ix1 -> Ix1 -> r) -> ((# #) -> r) -> r
Ix3 i3 i2 i1 = i3 :> i2 :. i1

{-# COMPLETE Ix3 #-}

-- | 3-dimensional size constructor. @(Sz3 i j k) == Sz (i :> j :. k)@
--
-- @since 0.3.0
pattern Sz3 :: Int -> Int -> Int -> Sz Ix3
pattern $bSz3 :: Ix1 -> Ix1 -> Ix1 -> Sz (IxN 3)
$mSz3 :: forall {r}.
Sz (IxN 3) -> (Ix1 -> Ix1 -> Ix1 -> r) -> ((# #) -> r) -> r
Sz3 i3 i2 i1 = Sz (i3 :> i2 :. i1)

{-# COMPLETE Sz3 #-}

-- | 4-dimensional type synonym.
--
-- @since 0.1.0
type Ix4 = IxN 4

-- | 4-dimensional index constructor. @(Ix4 i j k l) == (i :> j :> k :. l)@
--
-- @since 0.1.0
pattern Ix4 :: Int -> Int -> Int -> Int -> Ix4
pattern $bIx4 :: Ix1 -> Ix1 -> Ix1 -> Ix1 -> Ix4
$mIx4 :: forall {r}.
Ix4 -> (Ix1 -> Ix1 -> Ix1 -> Ix1 -> r) -> ((# #) -> r) -> r
Ix4 i4 i3 i2 i1 = i4 :> i3 :> i2 :. i1

{-# COMPLETE Ix4 #-}

-- | 4-dimensional size constructor. @(Sz4 i j k l) == Sz (i :> j :> k :. l)@
--
-- @since 0.3.0
pattern Sz4 :: Int -> Int -> Int -> Int -> Sz Ix4
pattern $bSz4 :: Ix1 -> Ix1 -> Ix1 -> Ix1 -> Sz Ix4
$mSz4 :: forall {r}.
Sz Ix4 -> (Ix1 -> Ix1 -> Ix1 -> Ix1 -> r) -> ((# #) -> r) -> r
Sz4 i4 i3 i2 i1 = Sz (i4 :> i3 :> i2 :. i1)

{-# COMPLETE Sz4 #-}

-- | 5-dimensional type synonym.
--
-- @since 0.1.0
type Ix5 = IxN 5

-- | 5-dimensional index constructor.  @(Ix5 i j k l m) == (i :> j :> k :> l :. m)@
--
-- @since 0.1.0
pattern Ix5 :: Int -> Int -> Int -> Int -> Int -> Ix5
pattern $bIx5 :: Ix1 -> Ix1 -> Ix1 -> Ix1 -> Ix1 -> Ix5
$mIx5 :: forall {r}.
Ix5 -> (Ix1 -> Ix1 -> Ix1 -> Ix1 -> Ix1 -> r) -> ((# #) -> r) -> r
Ix5 i5 i4 i3 i2 i1 = i5 :> i4 :> i3 :> i2 :. i1

{-# COMPLETE Ix5 #-}

-- | 5-dimensional size constructor.  @(Sz5 i j k l m) == Sz (i :> j :> k :> l :. m)@
--
-- @since 0.3.0
pattern Sz5 :: Int -> Int -> Int -> Int -> Int -> Sz Ix5
pattern $bSz5 :: Ix1 -> Ix1 -> Ix1 -> Ix1 -> Ix1 -> Sz Ix5
$mSz5 :: forall {r}.
Sz Ix5
-> (Ix1 -> Ix1 -> Ix1 -> Ix1 -> Ix1 -> r) -> ((# #) -> r) -> r
Sz5 i5 i4 i3 i2 i1 = Sz (i5 :> i4 :> i3 :> i2 :. i1)

{-# COMPLETE Sz5 #-}

-- | n-dimensional index. Needs a base case, which is the `Ix2`.
--
-- @since 0.1.0
data IxN (n :: Nat) = {-# UNPACK #-} !Int :> !(Ix (n - 1))

-- | Defines n-dimensional index by relating a general `IxN` with few base cases.
--
-- @since 0.1.0
type family Ix (n :: Nat) = r | r -> n where
  Ix 0 = Ix0
  Ix 1 = Ix1
  Ix 2 = Ix2
  Ix n = IxN n

type instance Lower Ix2 = Ix1
type instance Lower (IxN n) = Ix (n - 1)

instance Show Ix2 where
  showsPrec :: Ix1 -> Ix2 -> ShowS
showsPrec Ix1
n (Ix1
i :. Ix1
j) = Ix1 -> ShowS -> ShowS
showsPrecWrapped Ix1
n (forall a. Show a => a -> ShowS
shows Ix1
i forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String
" :. " forall a. [a] -> [a] -> [a]
++) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows Ix1
j)

instance Show (Ix (n - 1)) => Show (IxN n) where
  showsPrec :: Ix1 -> IxN n -> ShowS
showsPrec Ix1
n (Ix1
i :> Ix (n - 1)
ix) = Ix1 -> ShowS -> ShowS
showsPrecWrapped Ix1
n (forall a. Show a => a -> ShowS
shows Ix1
i forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String
" :> " forall a. [a] -> [a] -> [a]
++) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows Ix (n - 1)
ix)

instance Uniform Ix2 where
  uniformM :: forall g (m :: * -> *). StatefulGen g m => g -> m Ix2
uniformM g
g = Ix1 -> Ix1 -> Ix2
(:.) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a g (m :: * -> *). (Uniform a, StatefulGen g m) => g -> m a
uniformM g
g forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a g (m :: * -> *). (Uniform a, StatefulGen g m) => g -> m a
uniformM g
g
  {-# INLINE uniformM #-}

instance UniformRange Ix2 where
  uniformRM :: forall g (m :: * -> *). StatefulGen g m => (Ix2, Ix2) -> g -> m Ix2
uniformRM (Ix1
l1 :. Ix1
l2, Ix1
u1 :. Ix1
u2) g
g = Ix1 -> Ix1 -> Ix2
(:.) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a g (m :: * -> *).
(UniformRange a, StatefulGen g m) =>
(a, a) -> g -> m a
uniformRM (Ix1
l1, Ix1
u1) g
g forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a g (m :: * -> *).
(UniformRange a, StatefulGen g m) =>
(a, a) -> g -> m a
uniformRM (Ix1
l2, Ix1
u2) g
g
  {-# INLINE uniformRM #-}

instance Random Ix2

instance Uniform (Ix (n - 1)) => Uniform (IxN n) where
  uniformM :: forall g (m :: * -> *). StatefulGen g m => g -> m (IxN n)
uniformM g
g = forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
(:>) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a g (m :: * -> *). (Uniform a, StatefulGen g m) => g -> m a
uniformM g
g forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a g (m :: * -> *). (Uniform a, StatefulGen g m) => g -> m a
uniformM g
g
  {-# INLINE uniformM #-}

instance UniformRange (Ix (n - 1)) => UniformRange (IxN n) where
  uniformRM :: forall g (m :: * -> *).
StatefulGen g m =>
(IxN n, IxN n) -> g -> m (IxN n)
uniformRM (Ix1
l1 :> Ix (n - 1)
l2, Ix1
u1 :> Ix (n - 1)
u2) g
g = forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
(:>) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a g (m :: * -> *).
(UniformRange a, StatefulGen g m) =>
(a, a) -> g -> m a
uniformRM (Ix1
l1, Ix1
u1) g
g forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a g (m :: * -> *).
(UniformRange a, StatefulGen g m) =>
(a, a) -> g -> m a
uniformRM (Ix (n - 1)
l2, Ix (n - 1)
u2) g
g
  {-# INLINE uniformRM #-}

instance Random (Ix (n - 1)) => Random (IxN n) where
  random :: forall g. RandomGen g => g -> (IxN n, g)
random g
g =
    case forall a g. (Random a, RandomGen g) => g -> (a, g)
random g
g of
      (Ix1
i, g
g') ->
        case forall a g. (Random a, RandomGen g) => g -> (a, g)
random g
g' of
          (Ix (n - 1)
n, g
g'') -> (Ix1
i forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> Ix (n - 1)
n, g
g'')
  {-# INLINE random #-}
  randomR :: forall g. RandomGen g => (IxN n, IxN n) -> g -> (IxN n, g)
randomR (Ix1
l1 :> Ix (n - 1)
l2, Ix1
u1 :> Ix (n - 1)
u2) g
g =
    case forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (Ix1
l1, Ix1
u1) g
g of
      (Ix1
i, g
g') ->
        case forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
randomR (Ix (n - 1)
l2, Ix (n - 1)
u2) g
g' of
          (Ix (n - 1)
n, g
g'') -> (Ix1
i forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> Ix (n - 1)
n, g
g'')
  {-# INLINE randomR #-}

instance I.Ix Ix2 where
  range :: (Ix2, Ix2) -> [Ix2]
range (Ix1
i1 :. Ix1
j1, Ix1
i2 :. Ix1
j2) = [Ix1
i Ix1 -> Ix1 -> Ix2
:. Ix1
j | Ix1
i <- [Ix1
i1 .. Ix1
i2], Ix1
j <- [Ix1
j1 .. Ix1
j2]]
  {-# INLINE range #-}
  unsafeIndex :: (Ix2, Ix2) -> Ix2 -> Ix1
unsafeIndex (Ix1
l1 :. Ix1
l2, Ix1
u1 :. Ix1
u2) (Ix1
i1 :. Ix1
i2) =
    forall a. Ix a => (a, a) -> a -> Ix1
I.unsafeIndex (Ix1
l1, Ix1
u1) Ix1
i1 forall a. Num a => a -> a -> a
* forall a. Ix a => (a, a) -> Ix1
I.unsafeRangeSize (Ix1
l2, Ix1
u2) forall a. Num a => a -> a -> a
+ forall a. Ix a => (a, a) -> a -> Ix1
I.unsafeIndex (Ix1
l2, Ix1
u2) Ix1
i2
  {-# INLINE unsafeIndex #-}
  inRange :: (Ix2, Ix2) -> Ix2 -> Bool
inRange (Ix1
l1 :. Ix1
l2, Ix1
u1 :. Ix1
u2) (Ix1
i1 :. Ix1
i2) = forall a. Ix a => (a, a) -> a -> Bool
I.inRange (Ix1
l1, Ix1
u1) Ix1
i1 Bool -> Bool -> Bool
&& forall a. Ix a => (a, a) -> a -> Bool
I.inRange (Ix1
l2, Ix1
u2) Ix1
i2
  {-# INLINE inRange #-}

instance I.Ix (Ix (n - 1)) => I.Ix (IxN n) where
  range :: (IxN n, IxN n) -> [IxN n]
range (Ix1
i1 :> Ix (n - 1)
j1, Ix1
i2 :> Ix (n - 1)
j2) = [Ix1
i forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> Ix (n - 1)
j | Ix1
i <- [Ix1
i1 .. Ix1
i2], Ix (n - 1)
j <- forall a. Ix a => (a, a) -> [a]
I.range (Ix (n - 1)
j1, Ix (n - 1)
j2)]
  {-# INLINE range #-}
  unsafeIndex :: (IxN n, IxN n) -> IxN n -> Ix1
unsafeIndex (Ix1
l1 :> Ix (n - 1)
l2, Ix1
u1 :> Ix (n - 1)
u2) (Ix1
i1 :> Ix (n - 1)
i2) =
    forall a. Ix a => (a, a) -> a -> Ix1
I.unsafeIndex (Ix1
l1, Ix1
u1) Ix1
i1 forall a. Num a => a -> a -> a
* forall a. Ix a => (a, a) -> Ix1
I.unsafeRangeSize (Ix (n - 1)
l2, Ix (n - 1)
u2) forall a. Num a => a -> a -> a
+ forall a. Ix a => (a, a) -> a -> Ix1
I.unsafeIndex (Ix (n - 1)
l2, Ix (n - 1)
u2) Ix (n - 1)
i2
  {-# INLINE unsafeIndex #-}
  inRange :: (IxN n, IxN n) -> IxN n -> Bool
inRange (Ix1
l1 :> Ix (n - 1)
l2, Ix1
u1 :> Ix (n - 1)
u2) (Ix1
i1 :> Ix (n - 1)
i2) = forall a. Ix a => (a, a) -> a -> Bool
I.inRange (Ix1
l1, Ix1
u1) Ix1
i1 Bool -> Bool -> Bool
&& forall a. Ix a => (a, a) -> a -> Bool
I.inRange (Ix (n - 1)
l2, Ix (n - 1)
u2) Ix (n - 1)
i2
  {-# INLINE inRange #-}

instance Num Ix2 where
  + :: Ix2 -> Ix2 -> Ix2
(+) = forall ix. Index ix => (Ix1 -> Ix1 -> Ix1) -> ix -> ix -> ix
liftIndex2 forall a. Num a => a -> a -> a
(+)
  {-# INLINE [1] (+) #-}
  (-) = forall ix. Index ix => (Ix1 -> Ix1 -> Ix1) -> ix -> ix -> ix
liftIndex2 (-)
  {-# INLINE [1] (-) #-}
  * :: Ix2 -> Ix2 -> Ix2
(*) = forall ix. Index ix => (Ix1 -> Ix1 -> Ix1) -> ix -> ix -> ix
liftIndex2 forall a. Num a => a -> a -> a
(*)
  {-# INLINE [1] (*) #-}
  negate :: Ix2 -> Ix2
negate = forall ix. Index ix => (Ix1 -> Ix1) -> ix -> ix
liftIndex forall a. Num a => a -> a
negate
  {-# INLINE [1] negate #-}
  abs :: Ix2 -> Ix2
abs = forall ix. Index ix => (Ix1 -> Ix1) -> ix -> ix
liftIndex forall a. Num a => a -> a
abs
  {-# INLINE [1] abs #-}
  signum :: Ix2 -> Ix2
signum = forall ix. Index ix => (Ix1 -> Ix1) -> ix -> ix
liftIndex forall a. Num a => a -> a
signum
  {-# INLINE [1] signum #-}
  fromInteger :: Integer -> Ix2
fromInteger = forall ix. Index ix => Ix1 -> ix
pureIndex forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Num a => Integer -> a
fromInteger
  {-# INLINE [1] fromInteger #-}

instance Num Ix3 where
  + :: IxN 3 -> IxN 3 -> IxN 3
(+) = forall ix. Index ix => (Ix1 -> Ix1 -> Ix1) -> ix -> ix -> ix
liftIndex2 forall a. Num a => a -> a -> a
(+)
  {-# INLINE [1] (+) #-}
  (-) = forall ix. Index ix => (Ix1 -> Ix1 -> Ix1) -> ix -> ix -> ix
liftIndex2 (-)
  {-# INLINE [1] (-) #-}
  * :: IxN 3 -> IxN 3 -> IxN 3
(*) = forall ix. Index ix => (Ix1 -> Ix1 -> Ix1) -> ix -> ix -> ix
liftIndex2 forall a. Num a => a -> a -> a
(*)
  {-# INLINE [1] (*) #-}
  negate :: IxN 3 -> IxN 3
negate = forall ix. Index ix => (Ix1 -> Ix1) -> ix -> ix
liftIndex forall a. Num a => a -> a
negate
  {-# INLINE [1] negate #-}
  abs :: IxN 3 -> IxN 3
abs = forall ix. Index ix => (Ix1 -> Ix1) -> ix -> ix
liftIndex forall a. Num a => a -> a
abs
  {-# INLINE [1] abs #-}
  signum :: IxN 3 -> IxN 3
signum = forall ix. Index ix => (Ix1 -> Ix1) -> ix -> ix
liftIndex forall a. Num a => a -> a
signum
  {-# INLINE [1] signum #-}
  fromInteger :: Integer -> IxN 3
fromInteger = forall ix. Index ix => Ix1 -> ix
pureIndex forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Num a => Integer -> a
fromInteger
  {-# INLINE [1] fromInteger #-}

instance {-# OVERLAPPABLE #-} HighIxN n => Num (IxN n) where
  + :: IxN n -> IxN n -> IxN n
(+) = forall ix. Index ix => (Ix1 -> Ix1 -> Ix1) -> ix -> ix -> ix
liftIndex2 forall a. Num a => a -> a -> a
(+)
  {-# INLINE [1] (+) #-}
  (-) = forall ix. Index ix => (Ix1 -> Ix1 -> Ix1) -> ix -> ix -> ix
liftIndex2 (-)
  {-# INLINE [1] (-) #-}
  * :: IxN n -> IxN n -> IxN n
(*) = forall ix. Index ix => (Ix1 -> Ix1 -> Ix1) -> ix -> ix -> ix
liftIndex2 forall a. Num a => a -> a -> a
(*)
  {-# INLINE [1] (*) #-}
  negate :: IxN n -> IxN n
negate = forall ix. Index ix => (Ix1 -> Ix1) -> ix -> ix
liftIndex forall a. Num a => a -> a
negate
  {-# INLINE [1] negate #-}
  abs :: IxN n -> IxN n
abs = forall ix. Index ix => (Ix1 -> Ix1) -> ix -> ix
liftIndex forall a. Num a => a -> a
abs
  {-# INLINE [1] abs #-}
  signum :: IxN n -> IxN n
signum = forall ix. Index ix => (Ix1 -> Ix1) -> ix -> ix
liftIndex forall a. Num a => a -> a
signum
  {-# INLINE [1] signum #-}
  fromInteger :: Integer -> IxN n
fromInteger = forall ix. Index ix => Ix1 -> ix
pureIndex forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Num a => Integer -> a
fromInteger
  {-# INLINE [1] fromInteger #-}

instance Bounded Ix2 where
  minBound :: Ix2
minBound = forall ix. Index ix => Ix1 -> ix
pureIndex forall a. Bounded a => a
minBound
  {-# INLINE minBound #-}
  maxBound :: Ix2
maxBound = forall ix. Index ix => Ix1 -> ix
pureIndex forall a. Bounded a => a
maxBound
  {-# INLINE maxBound #-}

instance Bounded Ix3 where
  minBound :: IxN 3
minBound = forall ix. Index ix => Ix1 -> ix
pureIndex forall a. Bounded a => a
minBound
  {-# INLINE minBound #-}
  maxBound :: IxN 3
maxBound = forall ix. Index ix => Ix1 -> ix
pureIndex forall a. Bounded a => a
maxBound
  {-# INLINE maxBound #-}

instance {-# OVERLAPPABLE #-} HighIxN n => Bounded (IxN n) where
  minBound :: IxN n
minBound = forall ix. Index ix => Ix1 -> ix
pureIndex forall a. Bounded a => a
minBound
  {-# INLINE minBound #-}
  maxBound :: IxN n
maxBound = forall ix. Index ix => Ix1 -> ix
pureIndex forall a. Bounded a => a
maxBound
  {-# INLINE maxBound #-}

instance NFData Ix2 where
  rnf :: Ix2 -> ()
rnf Ix2
ix = Ix2
ix seq :: forall a b. a -> b -> b
`seq` ()

instance NFData (IxN n) where
  rnf :: IxN n -> ()
rnf IxN n
ix = IxN n
ix seq :: forall a b. a -> b -> b
`seq` ()

instance Eq Ix2 where
  (Ix1
i1 :. Ix1
j1) == :: Ix2 -> Ix2 -> Bool
== (Ix1
i2 :. Ix1
j2) = Ix1
i1 forall a. Eq a => a -> a -> Bool
== Ix1
i2 Bool -> Bool -> Bool
&& Ix1
j1 forall a. Eq a => a -> a -> Bool
== Ix1
j2

instance Eq (Ix (n - 1)) => Eq (IxN n) where
  (Ix1
i1 :> Ix (n - 1)
ix1) == :: IxN n -> IxN n -> Bool
== (Ix1
i2 :> Ix (n - 1)
ix2) = Ix1
i1 forall a. Eq a => a -> a -> Bool
== Ix1
i2 Bool -> Bool -> Bool
&& Ix (n - 1)
ix1 forall a. Eq a => a -> a -> Bool
== Ix (n - 1)
ix2

instance Ord Ix2 where
  compare :: Ix2 -> Ix2 -> Ordering
compare (Ix1
i1 :. Ix1
j1) (Ix1
i2 :. Ix1
j2) = forall a. Ord a => a -> a -> Ordering
compare Ix1
i1 Ix1
i2 forall a. Semigroup a => a -> a -> a
<> forall a. Ord a => a -> a -> Ordering
compare Ix1
j1 Ix1
j2

instance Ord (Ix (n - 1)) => Ord (IxN n) where
  compare :: IxN n -> IxN n -> Ordering
compare (Ix1
i1 :> Ix (n - 1)
ix1) (Ix1
i2 :> Ix (n - 1)
ix2) = forall a. Ord a => a -> a -> Ordering
compare Ix1
i1 Ix1
i2 forall a. Semigroup a => a -> a -> a
<> forall a. Ord a => a -> a -> Ordering
compare Ix (n - 1)
ix1 Ix (n - 1)
ix2

instance Index Ix2 where
  type Dimensions Ix2 = 2
  dimensions :: forall (proxy :: * -> *). proxy Ix2 -> Dim
dimensions proxy Ix2
_ = Dim
2
  {-# INLINE [1] dimensions #-}
  totalElem :: Sz Ix2 -> Ix1
totalElem (SafeSz (Ix1
k2 :. Ix1
k1)) = Ix1
k2 forall a. Num a => a -> a -> a
* Ix1
k1
  {-# INLINE [1] totalElem #-}
  isSafeIndex :: Sz Ix2 -> Ix2 -> Bool
isSafeIndex (SafeSz (Ix1
k2 :. Ix1
k1)) (Ix1
i2 :. Ix1
i1) = Ix1
0 forall a. Ord a => a -> a -> Bool
<= Ix1
i2 Bool -> Bool -> Bool
&& Ix1
0 forall a. Ord a => a -> a -> Bool
<= Ix1
i1 Bool -> Bool -> Bool
&& Ix1
i2 forall a. Ord a => a -> a -> Bool
< Ix1
k2 Bool -> Bool -> Bool
&& Ix1
i1 forall a. Ord a => a -> a -> Bool
< Ix1
k1
  {-# INLINE [1] isSafeIndex #-}
  toLinearIndex :: Sz Ix2 -> Ix2 -> Ix1
toLinearIndex (SafeSz (Ix1
_ :. Ix1
k1)) (Ix1
i2 :. Ix1
i1) = Ix1
k1 forall a. Num a => a -> a -> a
* Ix1
i2 forall a. Num a => a -> a -> a
+ Ix1
i1
  {-# INLINE [1] toLinearIndex #-}
  fromLinearIndex :: Sz Ix2 -> Ix1 -> Ix2
fromLinearIndex (SafeSz (Ix1
_ :. Ix1
k1)) Ix1
i =
    case Ix1
i forall a. Integral a => a -> a -> (a, a)
`quotRem` Ix1
k1 of
      (Ix1
i2, Ix1
i1) -> Ix1
i2 Ix1 -> Ix1 -> Ix2
:. Ix1
i1
  {-# INLINE [1] fromLinearIndex #-}
  consDim :: Ix1 -> Lower Ix2 -> Ix2
consDim = Ix1 -> Ix1 -> Ix2
(:.)
  {-# INLINE [1] consDim #-}
  unconsDim :: Ix2 -> (Ix1, Lower Ix2)
unconsDim (Ix1
i2 :. Ix1
i1) = (Ix1
i2, Ix1
i1)
  {-# INLINE [1] unconsDim #-}
  snocDim :: Lower Ix2 -> Ix1 -> Ix2
snocDim Lower Ix2
i2 Ix1
i1 = Lower Ix2
i2 Ix1 -> Ix1 -> Ix2
:. Ix1
i1
  {-# INLINE [1] snocDim #-}
  unsnocDim :: Ix2 -> (Lower Ix2, Ix1)
unsnocDim (Ix1
i2 :. Ix1
i1) = (Ix1
i2, Ix1
i1)
  {-# INLINE [1] unsnocDim #-}
  getDimM :: forall (m :: * -> *). MonadThrow m => Ix2 -> Dim -> m Ix1
getDimM (Ix1
i2 :. Ix1
_) Dim
2 = forall (f :: * -> *) a. Applicative f => a -> f a
pure Ix1
i2
  getDimM (Ix1
_ :. Ix1
i1) Dim
1 = forall (f :: * -> *) a. Applicative f => a -> f a
pure Ix1
i1
  getDimM Ix2
ix Dim
d = forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Ix2
ix Dim
d
  {-# INLINE [1] getDimM #-}
  setDimM :: forall (m :: * -> *). MonadThrow m => Ix2 -> Dim -> Ix1 -> m Ix2
setDimM (Ix1
_ :. Ix1
i1) Dim
2 Ix1
i2 = forall (f :: * -> *) a. Applicative f => a -> f a
pure (Ix1
i2 Ix1 -> Ix1 -> Ix2
:. Ix1
i1)
  setDimM (Ix1
i2 :. Ix1
_) Dim
1 Ix1
i1 = forall (f :: * -> *) a. Applicative f => a -> f a
pure (Ix1
i2 Ix1 -> Ix1 -> Ix2
:. Ix1
i1)
  setDimM Ix2
ix Dim
d Ix1
_ = forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Ix2
ix Dim
d
  {-# INLINE [1] setDimM #-}
  pullOutDimM :: forall (m :: * -> *).
MonadThrow m =>
Ix2 -> Dim -> m (Ix1, Lower Ix2)
pullOutDimM (Ix1
i2 :. Ix1
i1) Dim
2 = forall (f :: * -> *) a. Applicative f => a -> f a
pure (Ix1
i2, Ix1
i1)
  pullOutDimM (Ix1
i2 :. Ix1
i1) Dim
1 = forall (f :: * -> *) a. Applicative f => a -> f a
pure (Ix1
i1, Ix1
i2)
  pullOutDimM Ix2
ix Dim
d = forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Ix2
ix Dim
d
  {-# INLINE [1] pullOutDimM #-}
  insertDimM :: forall (m :: * -> *).
MonadThrow m =>
Lower Ix2 -> Dim -> Ix1 -> m Ix2
insertDimM Lower Ix2
i1 Dim
2 Ix1
i2 = forall (f :: * -> *) a. Applicative f => a -> f a
pure (Ix1
i2 Ix1 -> Ix1 -> Ix2
:. Lower Ix2
i1)
  insertDimM Lower Ix2
i2 Dim
1 Ix1
i1 = forall (f :: * -> *) a. Applicative f => a -> f a
pure (Lower Ix2
i2 Ix1 -> Ix1 -> Ix2
:. Ix1
i1)
  insertDimM Lower Ix2
ix Dim
d Ix1
_ = forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Lower Ix2
ix Dim
d
  {-# INLINE [1] insertDimM #-}
  pureIndex :: Ix1 -> Ix2
pureIndex Ix1
i = Ix1
i Ix1 -> Ix1 -> Ix2
:. Ix1
i
  {-# INLINE [1] pureIndex #-}
  liftIndex :: (Ix1 -> Ix1) -> Ix2 -> Ix2
liftIndex Ix1 -> Ix1
f (Ix1
i2 :. Ix1
i1) = Ix1 -> Ix1
f Ix1
i2 Ix1 -> Ix1 -> Ix2
:. Ix1 -> Ix1
f Ix1
i1
  {-# INLINE [1] liftIndex #-}
  liftIndex2 :: (Ix1 -> Ix1 -> Ix1) -> Ix2 -> Ix2 -> Ix2
liftIndex2 Ix1 -> Ix1 -> Ix1
f (Ix1
i2 :. Ix1
i1) (Ix1
i2' :. Ix1
i1') = Ix1 -> Ix1 -> Ix1
f Ix1
i2 Ix1
i2' Ix1 -> Ix1 -> Ix2
:. Ix1 -> Ix1 -> Ix1
f Ix1
i1 Ix1
i1'
  {-# INLINE [1] liftIndex2 #-}
  repairIndex :: Sz Ix2
-> Ix2 -> (Sz Ix1 -> Ix1 -> Ix1) -> (Sz Ix1 -> Ix1 -> Ix1) -> Ix2
repairIndex (SafeSz (Ix1
k :. Ix1
szL)) (Ix1
i :. Ix1
ixL) Sz Ix1 -> Ix1 -> Ix1
rBelow Sz Ix1 -> Ix1 -> Ix1
rOver =
    forall ix.
Index ix =>
Sz ix
-> ix -> (Sz Ix1 -> Ix1 -> Ix1) -> (Sz Ix1 -> Ix1 -> Ix1) -> ix
repairIndex (forall ix. ix -> Sz ix
SafeSz Ix1
k) Ix1
i Sz Ix1 -> Ix1 -> Ix1
rBelow Sz Ix1 -> Ix1 -> Ix1
rOver Ix1 -> Ix1 -> Ix2
:. forall ix.
Index ix =>
Sz ix
-> ix -> (Sz Ix1 -> Ix1 -> Ix1) -> (Sz Ix1 -> Ix1 -> Ix1) -> ix
repairIndex (forall ix. ix -> Sz ix
SafeSz Ix1
szL) Ix1
ixL Sz Ix1 -> Ix1 -> Ix1
rBelow Sz Ix1 -> Ix1 -> Ix1
rOver
  {-# INLINE [1] repairIndex #-}
  iterF :: forall (f :: * -> *) a.
Ix2
-> Ix2
-> Ix2
-> (Ix1 -> Ix1 -> Bool)
-> f a
-> (Ix2 -> f a -> f a)
-> f a
iterF (Ix1
s :. Ix1
sIxL) (Ix1
e :. Ix1
eIxL) (Ix1
inc :. Ix1
incIxL) Ix1 -> Ix1 -> Bool
cond f a
initAct Ix2 -> f a -> f a
f =
    forall (f :: * -> *) a.
Ix1
-> (Ix1 -> Bool)
-> (Ix1 -> Ix1)
-> f a
-> (Ix1 -> f a -> f a)
-> f a
loopF Ix1
s (Ix1 -> Ix1 -> Bool
`cond` Ix1
e) (forall a. Num a => a -> a -> a
+ Ix1
inc) f a
initAct forall a b. (a -> b) -> a -> b
$ \ !Ix1
i f a
g ->
      forall (f :: * -> *) a.
Ix1
-> (Ix1 -> Bool)
-> (Ix1 -> Ix1)
-> f a
-> (Ix1 -> f a -> f a)
-> f a
loopF Ix1
sIxL (Ix1 -> Ix1 -> Bool
`cond` Ix1
eIxL) (forall a. Num a => a -> a -> a
+ Ix1
incIxL) f a
g forall a b. (a -> b) -> a -> b
$ \ !Ix1
j -> Ix2 -> f a -> f a
f (Ix1
i Ix1 -> Ix1 -> Ix2
:. Ix1
j)
  {-# INLINE iterF #-}

instance {-# OVERLAPPING #-} Index (IxN 3) where
  type Dimensions Ix3 = 3
  dimensions :: forall (proxy :: * -> *). proxy (IxN 3) -> Dim
dimensions proxy (IxN 3)
_ = Dim
3
  {-# INLINE [1] dimensions #-}
  totalElem :: Sz (IxN 3) -> Ix1
totalElem (SafeSz (Ix1
k3 :> Ix1
k2 :. Ix1
k1)) = Ix1
k3 forall a. Num a => a -> a -> a
* Ix1
k2 forall a. Num a => a -> a -> a
* Ix1
k1
  {-# INLINE [1] totalElem #-}
  isSafeIndex :: Sz (IxN 3) -> IxN 3 -> Bool
isSafeIndex (SafeSz (Ix1
k3 :> Ix1
k2 :. Ix1
k1)) (Ix1
i3 :> Ix1
i2 :. Ix1
i1) =
    Ix1
0 forall a. Ord a => a -> a -> Bool
<= Ix1
i3 Bool -> Bool -> Bool
&& Ix1
0 forall a. Ord a => a -> a -> Bool
<= Ix1
i2 Bool -> Bool -> Bool
&& Ix1
0 forall a. Ord a => a -> a -> Bool
<= Ix1
i1 Bool -> Bool -> Bool
&& Ix1
i3 forall a. Ord a => a -> a -> Bool
< Ix1
k3 Bool -> Bool -> Bool
&& Ix1
i2 forall a. Ord a => a -> a -> Bool
< Ix1
k2 Bool -> Bool -> Bool
&& Ix1
i1 forall a. Ord a => a -> a -> Bool
< Ix1
k1
  {-# INLINE [1] isSafeIndex #-}
  toLinearIndex :: Sz (IxN 3) -> IxN 3 -> Ix1
toLinearIndex (SafeSz (Ix1
_ :> Ix1
k2 :. Ix1
k1)) (Ix1
i3 :> Ix1
i2 :. Ix1
i1) = (Ix1
i3 forall a. Num a => a -> a -> a
* Ix1
k2 forall a. Num a => a -> a -> a
+ Ix1
i2) forall a. Num a => a -> a -> a
* Ix1
k1 forall a. Num a => a -> a -> a
+ Ix1
i1
  {-# INLINE [1] toLinearIndex #-}
  fromLinearIndex :: Sz (IxN 3) -> Ix1 -> IxN 3
fromLinearIndex (SafeSz (Ix1
_ :> Ix (3 - 1)
ix)) Ix1
i = let !(Ix1
q, Ix2
ixL) = forall ix. Index ix => ix -> Ix1 -> (Ix1, ix)
fromLinearIndexAcc Ix (3 - 1)
ix Ix1
i in Ix1
q forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> Ix2
ixL
  {-# INLINE fromLinearIndex #-}
  fromLinearIndexAcc :: IxN 3 -> Ix1 -> (Ix1, IxN 3)
fromLinearIndexAcc (Ix1
m :> Ix (3 - 1)
ix) !Ix1
k = (Ix1
q, Ix1
r forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> Ix2
ixL)
    where
      !(!Ix1
kL, !Ix2
ixL) = forall ix. Index ix => ix -> Ix1 -> (Ix1, ix)
fromLinearIndexAcc Ix (3 - 1)
ix Ix1
k
      !(!Ix1
q, !Ix1
r) = forall a. Integral a => a -> a -> (a, a)
quotRem Ix1
kL Ix1
m
  {-# INLINE fromLinearIndexAcc #-}
  consDim :: Ix1 -> Lower (IxN 3) -> IxN 3
consDim = forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
(:>)
  {-# INLINE [1] consDim #-}
  unconsDim :: IxN 3 -> (Ix1, Lower (IxN 3))
unconsDim (Ix1
i3 :> Ix (3 - 1)
ix) = (Ix1
i3, Ix (3 - 1)
ix)
  {-# INLINE [1] unconsDim #-}
  snocDim :: Lower (IxN 3) -> Ix1 -> IxN 3
snocDim (Ix1
i3 :. Ix1
i2) Ix1
i1 = Ix1
i3 forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> Ix1
i2 Ix1 -> Ix1 -> Ix2
:. Ix1
i1
  {-# INLINE [1] snocDim #-}
  unsnocDim :: IxN 3 -> (Lower (IxN 3), Ix1)
unsnocDim (Ix1
i3 :> Ix1
i2 :. Ix1
i1) = (Ix1
i3 Ix1 -> Ix1 -> Ix2
:. Ix1
i2, Ix1
i1)
  {-# INLINE [1] unsnocDim #-}
  getDimM :: forall (m :: * -> *). MonadThrow m => IxN 3 -> Dim -> m Ix1
getDimM (Ix1
i3 :> Ix1
_ :. Ix1
_) Dim
3 = forall (f :: * -> *) a. Applicative f => a -> f a
pure Ix1
i3
  getDimM (Ix1
_ :> Ix1
i2 :. Ix1
_) Dim
2 = forall (f :: * -> *) a. Applicative f => a -> f a
pure Ix1
i2
  getDimM (Ix1
_ :> Ix1
_ :. Ix1
i1) Dim
1 = forall (f :: * -> *) a. Applicative f => a -> f a
pure Ix1
i1
  getDimM IxN 3
ix Dim
d = forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException IxN 3
ix Dim
d
  {-# INLINE [1] getDimM #-}
  setDimM :: forall (m :: * -> *).
MonadThrow m =>
IxN 3 -> Dim -> Ix1 -> m (IxN 3)
setDimM (Ix1
_ :> Ix1
i2 :. Ix1
i1) Dim
3 Ix1
i3 = forall (f :: * -> *) a. Applicative f => a -> f a
pure (Ix1
i3 forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> Ix1
i2 Ix1 -> Ix1 -> Ix2
:. Ix1
i1)
  setDimM (Ix1
i3 :> Ix1
_ :. Ix1
i1) Dim
2 Ix1
i2 = forall (f :: * -> *) a. Applicative f => a -> f a
pure (Ix1
i3 forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> Ix1
i2 Ix1 -> Ix1 -> Ix2
:. Ix1
i1)
  setDimM (Ix1
i3 :> Ix1
i2 :. Ix1
_) Dim
1 Ix1
i1 = forall (f :: * -> *) a. Applicative f => a -> f a
pure (Ix1
i3 forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> Ix1
i2 Ix1 -> Ix1 -> Ix2
:. Ix1
i1)
  setDimM IxN 3
ix Dim
d Ix1
_ = forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException IxN 3
ix Dim
d
  {-# INLINE [1] setDimM #-}
  pullOutDimM :: forall (m :: * -> *).
MonadThrow m =>
IxN 3 -> Dim -> m (Ix1, Lower (IxN 3))
pullOutDimM (Ix1
i3 :> Ix1
i2 :. Ix1
i1) Dim
3 = forall (f :: * -> *) a. Applicative f => a -> f a
pure (Ix1
i3, Ix1
i2 Ix1 -> Ix1 -> Ix2
:. Ix1
i1)
  pullOutDimM (Ix1
i3 :> Ix1
i2 :. Ix1
i1) Dim
2 = forall (f :: * -> *) a. Applicative f => a -> f a
pure (Ix1
i2, Ix1
i3 Ix1 -> Ix1 -> Ix2
:. Ix1
i1)
  pullOutDimM (Ix1
i3 :> Ix1
i2 :. Ix1
i1) Dim
1 = forall (f :: * -> *) a. Applicative f => a -> f a
pure (Ix1
i1, Ix1
i3 Ix1 -> Ix1 -> Ix2
:. Ix1
i2)
  pullOutDimM IxN 3
ix Dim
d = forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException IxN 3
ix Dim
d
  {-# INLINE [1] pullOutDimM #-}
  insertDimM :: forall (m :: * -> *).
MonadThrow m =>
Lower (IxN 3) -> Dim -> Ix1 -> m (IxN 3)
insertDimM (Ix1
i2 :. Ix1
i1) Dim
3 Ix1
i3 = forall (f :: * -> *) a. Applicative f => a -> f a
pure (Ix1
i3 forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> Ix1
i2 Ix1 -> Ix1 -> Ix2
:. Ix1
i1)
  insertDimM (Ix1
i3 :. Ix1
i1) Dim
2 Ix1
i2 = forall (f :: * -> *) a. Applicative f => a -> f a
pure (Ix1
i3 forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> Ix1
i2 Ix1 -> Ix1 -> Ix2
:. Ix1
i1)
  insertDimM (Ix1
i3 :. Ix1
i2) Dim
1 Ix1
i1 = forall (f :: * -> *) a. Applicative f => a -> f a
pure (Ix1
i3 forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> Ix1
i2 Ix1 -> Ix1 -> Ix2
:. Ix1
i1)
  insertDimM Lower (IxN 3)
ix Dim
d Ix1
_ = forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Lower (IxN 3)
ix Dim
d
  {-# INLINE [1] insertDimM #-}
  pureIndex :: Ix1 -> IxN 3
pureIndex Ix1
i = Ix1
i forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> Ix1
i Ix1 -> Ix1 -> Ix2
:. Ix1
i
  {-# INLINE [1] pureIndex #-}
  liftIndex :: (Ix1 -> Ix1) -> IxN 3 -> IxN 3
liftIndex Ix1 -> Ix1
f (Ix1
i3 :> Ix1
i2 :. Ix1
i1) = Ix1 -> Ix1
f Ix1
i3 forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> Ix1 -> Ix1
f Ix1
i2 Ix1 -> Ix1 -> Ix2
:. Ix1 -> Ix1
f Ix1
i1
  {-# INLINE [1] liftIndex #-}
  liftIndex2 :: (Ix1 -> Ix1 -> Ix1) -> IxN 3 -> IxN 3 -> IxN 3
liftIndex2 Ix1 -> Ix1 -> Ix1
f (Ix1
i3 :> Ix1
i2 :. Ix1
i1) (Ix1
i3' :> Ix1
i2' :. Ix1
i1') = Ix1 -> Ix1 -> Ix1
f Ix1
i3 Ix1
i3' forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> Ix1 -> Ix1 -> Ix1
f Ix1
i2 Ix1
i2' Ix1 -> Ix1 -> Ix2
:. Ix1 -> Ix1 -> Ix1
f Ix1
i1 Ix1
i1'
  {-# INLINE [1] liftIndex2 #-}
  repairIndex :: Sz (IxN 3)
-> IxN 3
-> (Sz Ix1 -> Ix1 -> Ix1)
-> (Sz Ix1 -> Ix1 -> Ix1)
-> IxN 3
repairIndex (SafeSz (Ix1
n :> Ix (3 - 1)
szL)) (Ix1
i :> Ix (3 - 1)
ixL) Sz Ix1 -> Ix1 -> Ix1
rBelow Sz Ix1 -> Ix1 -> Ix1
rOver =
    forall ix.
Index ix =>
Sz ix
-> ix -> (Sz Ix1 -> Ix1 -> Ix1) -> (Sz Ix1 -> Ix1 -> Ix1) -> ix
repairIndex (forall ix. ix -> Sz ix
SafeSz Ix1
n) Ix1
i Sz Ix1 -> Ix1 -> Ix1
rBelow Sz Ix1 -> Ix1 -> Ix1
rOver forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> forall ix.
Index ix =>
Sz ix
-> ix -> (Sz Ix1 -> Ix1 -> Ix1) -> (Sz Ix1 -> Ix1 -> Ix1) -> ix
repairIndex (forall ix. ix -> Sz ix
SafeSz Ix (3 - 1)
szL) Ix (3 - 1)
ixL Sz Ix1 -> Ix1 -> Ix1
rBelow Sz Ix1 -> Ix1 -> Ix1
rOver
  {-# INLINE [1] repairIndex #-}
  iterTargetRowMajorAccM :: forall (m :: * -> *) a.
Monad m =>
Ix1
-> Ix1
-> Sz (IxN 3)
-> IxN 3
-> IxN 3
-> a
-> (Ix1 -> IxN 3 -> a -> m a)
-> m a
iterTargetRowMajorAccM Ix1
iAcc Ix1
iStart Sz (IxN 3)
sz (Ix1
b3 :> Ix1
b2 :. Ix1
b1) (Ix1
s3 :> Ix1
s2 :. Ix1
s1) a
initAcc Ix1 -> IxN 3 -> a -> m a
action =
    let n :: Ix1
n = forall ix. Index ix => Sz ix -> Ix1
totalElem Sz (IxN 3)
sz
        iShift :: Ix1
iShift = Ix1
iStart forall a. Num a => a -> a -> a
+ Ix1
iAcc forall a. Num a => a -> a -> a
* Ix1
n
     in forall (m :: * -> *) a.
Monad m =>
Ix1
-> (Ix1 -> Bool) -> (Ix1 -> Ix1) -> a -> (Ix1 -> a -> m a) -> m a
loopM Ix1
0 (forall a. Ord a => a -> a -> Bool
< Ix1
n) (forall a. Num a => a -> a -> a
+ Ix1
1) a
initAcc forall a b. (a -> b) -> a -> b
$ \ !Ix1
i !a
acc ->
          let (Ix1
i3 :> Ix1
i2 :. Ix1
i1) = forall ix. Index ix => Sz ix -> Ix1 -> ix
fromLinearIndex Sz (IxN 3)
sz Ix1
i
           in Ix1 -> IxN 3 -> a -> m a
action (Ix1
iShift forall a. Num a => a -> a -> a
+ Ix1
i) ((Ix1
b3 forall a. Num a => a -> a -> a
+ Ix1
s3 forall a. Num a => a -> a -> a
* Ix1
i3) forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> (Ix1
b2 forall a. Num a => a -> a -> a
+ Ix1
s2 forall a. Num a => a -> a -> a
* Ix1
i2) Ix1 -> Ix1 -> Ix2
:. (Ix1
b1 forall a. Num a => a -> a -> a
+ Ix1
s1 forall a. Num a => a -> a -> a
* Ix1
i1)) a
acc
  {-# INLINE iterTargetRowMajorAccM #-}
  iterTargetRowMajorAccST_ :: forall s a.
Ix1
-> Ix1
-> Scheduler s ()
-> Ix1
-> Sz (IxN 3)
-> IxN 3
-> IxN 3
-> a
-> (a -> ST s (a, a))
-> (Ix1 -> IxN 3 -> a -> ST s a)
-> ST s ()
iterTargetRowMajorAccST_ Ix1
iAcc Ix1
fact Scheduler s ()
scheduler Ix1
iStart Sz (IxN 3)
sz (Ix1
b3 :> Ix1
b2 :. Ix1
b1) (Ix1
s3 :> Ix1
s2 :. Ix1
s1) a
acc a -> ST s (a, a)
splitAcc Ix1 -> IxN 3 -> a -> ST s a
action =
    let n :: Ix1
n = forall ix. Index ix => Sz ix -> Ix1
totalElem Sz (IxN 3)
sz
        iShift :: Ix1
iShift = Ix1
iStart forall a. Num a => a -> a -> a
+ Ix1
iAcc forall a. Num a => a -> a -> a
* Ix1
n
     in forall s a.
Ix1
-> Scheduler s ()
-> Ix1
-> Ix1
-> Ix1
-> a
-> (a -> ST s (a, a))
-> (Ix1 -> a -> ST s a)
-> ST s ()
iterLinearAccST_ Ix1
fact Scheduler s ()
scheduler Ix1
0 Ix1
1 Ix1
n a
acc a -> ST s (a, a)
splitAcc forall a b. (a -> b) -> a -> b
$ \ !Ix1
i ->
          let (Ix1
i3 :> Ix1
i2 :. Ix1
i1) = forall ix. Index ix => Sz ix -> Ix1 -> ix
fromLinearIndex Sz (IxN 3)
sz Ix1
i
           in Ix1 -> IxN 3 -> a -> ST s a
action (Ix1
iShift forall a. Num a => a -> a -> a
+ Ix1
i) ((Ix1
b3 forall a. Num a => a -> a -> a
+ Ix1
s3 forall a. Num a => a -> a -> a
* Ix1
i3) forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> (Ix1
b2 forall a. Num a => a -> a -> a
+ Ix1
s2 forall a. Num a => a -> a -> a
* Ix1
i2) Ix1 -> Ix1 -> Ix2
:. (Ix1
b1 forall a. Num a => a -> a -> a
+ Ix1
s1 forall a. Num a => a -> a -> a
* Ix1
i1))
  {-# INLINE iterTargetRowMajorAccST_ #-}
  iterTargetRowMajorAccST :: forall s a.
Ix1
-> Ix1
-> Scheduler s a
-> Ix1
-> Sz (IxN 3)
-> IxN 3
-> IxN 3
-> a
-> (a -> ST s (a, a))
-> (Ix1 -> IxN 3 -> a -> ST s a)
-> ST s a
iterTargetRowMajorAccST Ix1
iAcc Ix1
fact Scheduler s a
scheduler Ix1
iStart Sz (IxN 3)
sz (Ix1
b3 :> Ix1
b2 :. Ix1
b1) (Ix1
s3 :> Ix1
s2 :. Ix1
s1) a
acc a -> ST s (a, a)
splitAcc Ix1 -> IxN 3 -> a -> ST s a
action =
    let n :: Ix1
n = forall ix. Index ix => Sz ix -> Ix1
totalElem Sz (IxN 3)
sz
        iShift :: Ix1
iShift = Ix1
iStart forall a. Num a => a -> a -> a
+ Ix1
iAcc forall a. Num a => a -> a -> a
* Ix1
n
     in forall s a.
Ix1
-> Scheduler s a
-> Ix1
-> Ix1
-> Ix1
-> a
-> (a -> ST s (a, a))
-> (Ix1 -> a -> ST s a)
-> ST s a
iterLinearAccST Ix1
fact Scheduler s a
scheduler Ix1
0 Ix1
1 Ix1
n a
acc a -> ST s (a, a)
splitAcc forall a b. (a -> b) -> a -> b
$ \ !Ix1
i ->
          let (Ix1
i3 :> Ix1
i2 :. Ix1
i1) = forall ix. Index ix => Sz ix -> Ix1 -> ix
fromLinearIndex Sz (IxN 3)
sz Ix1
i
           in Ix1 -> IxN 3 -> a -> ST s a
action (Ix1
iShift forall a. Num a => a -> a -> a
+ Ix1
i) ((Ix1
b3 forall a. Num a => a -> a -> a
+ Ix1
s3 forall a. Num a => a -> a -> a
* Ix1
i3) forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> (Ix1
b2 forall a. Num a => a -> a -> a
+ Ix1
s2 forall a. Num a => a -> a -> a
* Ix1
i2) Ix1 -> Ix1 -> Ix2
:. (Ix1
b1 forall a. Num a => a -> a -> a
+ Ix1
s1 forall a. Num a => a -> a -> a
* Ix1
i1))
  {-# INLINE iterTargetRowMajorAccST #-}

-- | Constraint synonym that encapsulates all constraints needed for dimension 4 and higher.
--
-- @since 1.0.0
type HighIxN n =
  (4 <= n, KnownNat n, KnownNat (n - 1), Index (IxN (n - 1)), IxN (n - 1) ~ Ix (n - 1))

instance {-# OVERLAPPABLE #-} HighIxN n => Index (IxN n) where
  type Dimensions (IxN n) = n
  dimensions :: forall (proxy :: * -> *). proxy (IxN n) -> Dim
dimensions proxy (IxN n)
_ = forall a. Num a => Integer -> a
fromInteger forall a b. (a -> b) -> a -> b
$ forall (n :: Natural) (proxy :: Natural -> *).
KnownNat n =>
proxy n -> Integer
natVal (forall {k} (t :: k). Proxy t
Proxy :: Proxy n)
  {-# INLINE [1] dimensions #-}
  totalElem :: Sz (IxN n) -> Ix1
totalElem (SafeSz (Ix1
i :> Ix (n - 1)
ixl)) = forall ix a. Index ix => (a -> Ix1 -> a) -> a -> ix -> a
foldlIndex forall a. Num a => a -> a -> a
(*) Ix1
i Ix (n - 1)
ixl
  {-# INLINE [1] totalElem #-}
  consDim :: Ix1 -> Lower (IxN n) -> IxN n
consDim = forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
(:>)
  {-# INLINE [1] consDim #-}
  unconsDim :: IxN n -> (Ix1, Lower (IxN n))
unconsDim (Ix1
i :> Ix (n - 1)
ixl) = (Ix1
i, Ix (n - 1)
ixl)
  {-# INLINE [1] unconsDim #-}
  snocDim :: Lower (IxN n) -> Ix1 -> IxN n
snocDim (Ix1
i :> Ix ((n - 1) - 1)
ixl) Ix1
i1 = Ix1
i forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> forall ix. Index ix => Lower ix -> Ix1 -> ix
snocDim Ix ((n - 1) - 1)
ixl Ix1
i1
  {-# INLINE [1] snocDim #-}
  unsnocDim :: IxN n -> (Lower (IxN n), Ix1)
unsnocDim (Ix1
i :> Ix (n - 1)
ixl) =
    case forall ix. Index ix => ix -> (Lower ix, Ix1)
unsnocDim Ix (n - 1)
ixl of
      (Lower (IxN (n - 1))
ix, Ix1
i1) -> (Ix1
i forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> Lower (IxN (n - 1))
ix, Ix1
i1)
  {-# INLINE [1] unsnocDim #-}
  getDimM :: forall (m :: * -> *). MonadThrow m => IxN n -> Dim -> m Ix1
getDimM ix :: IxN n
ix@(Ix1
i :> Ix (n - 1)
ixl) Dim
d
    | Dim
d forall a. Eq a => a -> a -> Bool
== forall ix (proxy :: * -> *). Index ix => proxy ix -> Dim
dimensions (forall {k} (t :: k). Proxy t
Proxy :: Proxy (IxN n)) = forall (f :: * -> *) a. Applicative f => a -> f a
pure Ix1
i
    | Bool
otherwise = forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException IxN n
ix Dim
d) forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall ix (m :: * -> *).
(Index ix, MonadThrow m) =>
ix -> Dim -> m Ix1
getDimM Ix (n - 1)
ixl Dim
d)
  {-# INLINE [1] getDimM #-}
  setDimM :: forall (m :: * -> *).
MonadThrow m =>
IxN n -> Dim -> Ix1 -> m (IxN n)
setDimM ix :: IxN n
ix@(Ix1
i :> Ix (n - 1)
ixl) Dim
d Ix1
di
    | Dim
d forall a. Eq a => a -> a -> Bool
== forall ix (proxy :: * -> *). Index ix => proxy ix -> Dim
dimensions (forall {k} (t :: k). Proxy t
Proxy :: Proxy (IxN n)) = forall (f :: * -> *) a. Applicative f => a -> f a
pure (Ix1
di forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> Ix (n - 1)
ixl)
    | Bool
otherwise = forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException IxN n
ix Dim
d) (forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Ix1
i forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:>)) (forall ix (m :: * -> *).
(Index ix, MonadThrow m) =>
ix -> Dim -> Ix1 -> m ix
setDimM Ix (n - 1)
ixl Dim
d Ix1
di)
  {-# INLINE [1] setDimM #-}
  pullOutDimM :: forall (m :: * -> *).
MonadThrow m =>
IxN n -> Dim -> m (Ix1, Lower (IxN n))
pullOutDimM ix :: IxN n
ix@(Ix1
i :> Ix (n - 1)
ixl) Dim
d
    | Dim
d forall a. Eq a => a -> a -> Bool
== forall ix (proxy :: * -> *). Index ix => proxy ix -> Dim
dimensions (forall {k} (t :: k). Proxy t
Proxy :: Proxy (IxN n)) = forall (f :: * -> *) a. Applicative f => a -> f a
pure (Ix1
i, Ix (n - 1)
ixl)
    | Bool
otherwise =
        forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException IxN n
ix Dim
d) (forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Ix1
i forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:>)) (forall ix (m :: * -> *).
(Index ix, MonadThrow m) =>
ix -> Dim -> m (Ix1, Lower ix)
pullOutDimM Ix (n - 1)
ixl Dim
d)
  {-# INLINE [1] pullOutDimM #-}
  insertDimM :: forall (m :: * -> *).
MonadThrow m =>
Lower (IxN n) -> Dim -> Ix1 -> m (IxN n)
insertDimM ix :: Lower (IxN n)
ix@(Ix1
i :> Ix ((n - 1) - 1)
ixl) Dim
d Ix1
di
    | Dim
d forall a. Eq a => a -> a -> Bool
== forall ix (proxy :: * -> *). Index ix => proxy ix -> Dim
dimensions (forall {k} (t :: k). Proxy t
Proxy :: Proxy (IxN n)) = forall (f :: * -> *) a. Applicative f => a -> f a
pure (Ix1
di forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> Lower (IxN n)
ix)
    | Bool
otherwise =
        forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ forall ix.
(NFData ix, Eq ix, Show ix, Typeable ix) =>
ix -> Dim -> IndexException
IndexDimensionException Lower (IxN n)
ix Dim
d) (forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Ix1
i forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:>)) (forall ix (m :: * -> *).
(Index ix, MonadThrow m) =>
Lower ix -> Dim -> Ix1 -> m ix
insertDimM Ix ((n - 1) - 1)
ixl Dim
d Ix1
di)
  {-# INLINE [1] insertDimM #-}
  pureIndex :: Ix1 -> IxN n
pureIndex Ix1
i = Ix1
i forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> (forall ix. Index ix => Ix1 -> ix
pureIndex Ix1
i :: Ix (n - 1))
  {-# INLINE [1] pureIndex #-}
  liftIndex :: (Ix1 -> Ix1) -> IxN n -> IxN n
liftIndex Ix1 -> Ix1
f (Ix1
i :> Ix (n - 1)
ix) = Ix1 -> Ix1
f Ix1
i forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> forall ix. Index ix => (Ix1 -> Ix1) -> ix -> ix
liftIndex Ix1 -> Ix1
f Ix (n - 1)
ix
  {-# INLINE [1] liftIndex #-}
  liftIndex2 :: (Ix1 -> Ix1 -> Ix1) -> IxN n -> IxN n -> IxN n
liftIndex2 Ix1 -> Ix1 -> Ix1
f (Ix1
i :> Ix (n - 1)
ix) (Ix1
i' :> Ix (n - 1)
ix') = Ix1 -> Ix1 -> Ix1
f Ix1
i Ix1
i' forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> forall ix. Index ix => (Ix1 -> Ix1 -> Ix1) -> ix -> ix -> ix
liftIndex2 Ix1 -> Ix1 -> Ix1
f Ix (n - 1)
ix Ix (n - 1)
ix'
  {-# INLINE [1] liftIndex2 #-}
  repairIndex :: Sz (IxN n)
-> IxN n
-> (Sz Ix1 -> Ix1 -> Ix1)
-> (Sz Ix1 -> Ix1 -> Ix1)
-> IxN n
repairIndex (SafeSz (Ix1
n :> Ix (n - 1)
szL)) (Ix1
i :> Ix (n - 1)
ixL) Sz Ix1 -> Ix1 -> Ix1
rBelow Sz Ix1 -> Ix1 -> Ix1
rOver =
    forall ix.
Index ix =>
Sz ix
-> ix -> (Sz Ix1 -> Ix1 -> Ix1) -> (Sz Ix1 -> Ix1 -> Ix1) -> ix
repairIndex (forall ix. ix -> Sz ix
SafeSz Ix1
n) Ix1
i Sz Ix1 -> Ix1 -> Ix1
rBelow Sz Ix1 -> Ix1 -> Ix1
rOver forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> forall ix.
Index ix =>
Sz ix
-> ix -> (Sz Ix1 -> Ix1 -> Ix1) -> (Sz Ix1 -> Ix1 -> Ix1) -> ix
repairIndex (forall ix. ix -> Sz ix
SafeSz Ix (n - 1)
szL) Ix (n - 1)
ixL Sz Ix1 -> Ix1 -> Ix1
rBelow Sz Ix1 -> Ix1 -> Ix1
rOver
  {-# INLINE [1] repairIndex #-}

---- Unbox Ix

-- | Unboxing of a `Ix2`.
instance VU.Unbox Ix2

newtype instance VU.MVector s Ix2 = MV_Ix2 (VU.MVector s (Int, Int))

instance VM.MVector VU.MVector Ix2 where
  basicLength :: forall s. MVector s Ix2 -> Ix1
basicLength (MV_Ix2 MVector s (Ix1, Ix1)
mvec) = forall (v :: * -> * -> *) a s. MVector v a => v s a -> Ix1
VM.basicLength MVector s (Ix1, Ix1)
mvec
  {-# INLINE basicLength #-}
  basicUnsafeSlice :: forall s. Ix1 -> Ix1 -> MVector s Ix2 -> MVector s Ix2
basicUnsafeSlice Ix1
idx Ix1
len (MV_Ix2 MVector s (Ix1, Ix1)
mvec) = forall s. MVector s (Ix1, Ix1) -> MVector s Ix2
MV_Ix2 (forall (v :: * -> * -> *) a s.
MVector v a =>
Ix1 -> Ix1 -> v s a -> v s a
VM.basicUnsafeSlice Ix1
idx Ix1
len MVector s (Ix1, Ix1)
mvec)
  {-# INLINE basicUnsafeSlice #-}
  basicOverlaps :: forall s. MVector s Ix2 -> MVector s Ix2 -> Bool
basicOverlaps (MV_Ix2 MVector s (Ix1, Ix1)
mvec) (MV_Ix2 MVector s (Ix1, Ix1)
mvec') = forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> Bool
VM.basicOverlaps MVector s (Ix1, Ix1)
mvec MVector s (Ix1, Ix1)
mvec'
  {-# INLINE basicOverlaps #-}
  basicUnsafeNew :: forall s. Ix1 -> ST s (MVector s Ix2)
basicUnsafeNew Ix1
len = forall s. MVector s (Ix1, Ix1) -> MVector s Ix2
MV_Ix2 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (v :: * -> * -> *) a s. MVector v a => Ix1 -> ST s (v s a)
VM.basicUnsafeNew Ix1
len
  {-# INLINE basicUnsafeNew #-}
  basicUnsafeReplicate :: forall s. Ix1 -> Ix2 -> ST s (MVector s Ix2)
basicUnsafeReplicate Ix1
len (Ix1
i :. Ix1
j) = forall s. MVector s (Ix1, Ix1) -> MVector s Ix2
MV_Ix2 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (v :: * -> * -> *) a s.
MVector v a =>
Ix1 -> a -> ST s (v s a)
VM.basicUnsafeReplicate Ix1
len (Ix1
i, Ix1
j)
  {-# INLINE basicUnsafeReplicate #-}
  basicUnsafeRead :: forall s. MVector s Ix2 -> Ix1 -> ST s Ix2
basicUnsafeRead (MV_Ix2 MVector s (Ix1, Ix1)
mvec) Ix1
idx = forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Ix1 -> Ix1 -> Ix2
(:.) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> Ix1 -> ST s a
VM.basicUnsafeRead MVector s (Ix1, Ix1)
mvec Ix1
idx
  {-# INLINE basicUnsafeRead #-}
  basicUnsafeWrite :: forall s. MVector s Ix2 -> Ix1 -> Ix2 -> ST s ()
basicUnsafeWrite (MV_Ix2 MVector s (Ix1, Ix1)
mvec) Ix1
idx (Ix1
i :. Ix1
j) = forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> Ix1 -> a -> ST s ()
VM.basicUnsafeWrite MVector s (Ix1, Ix1)
mvec Ix1
idx (Ix1
i, Ix1
j)
  {-# INLINE basicUnsafeWrite #-}
  basicClear :: forall s. MVector s Ix2 -> ST s ()
basicClear (MV_Ix2 MVector s (Ix1, Ix1)
mvec) = forall (v :: * -> * -> *) a s. MVector v a => v s a -> ST s ()
VM.basicClear MVector s (Ix1, Ix1)
mvec
  {-# INLINE basicClear #-}
  basicSet :: forall s. MVector s Ix2 -> Ix2 -> ST s ()
basicSet (MV_Ix2 MVector s (Ix1, Ix1)
mvec) (Ix1
i :. Ix1
j) = forall (v :: * -> * -> *) a s. MVector v a => v s a -> a -> ST s ()
VM.basicSet MVector s (Ix1, Ix1)
mvec (Ix1
i, Ix1
j)
  {-# INLINE basicSet #-}
  basicUnsafeCopy :: forall s. MVector s Ix2 -> MVector s Ix2 -> ST s ()
basicUnsafeCopy (MV_Ix2 MVector s (Ix1, Ix1)
mvec) (MV_Ix2 MVector s (Ix1, Ix1)
mvec') = forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> ST s ()
VM.basicUnsafeCopy MVector s (Ix1, Ix1)
mvec MVector s (Ix1, Ix1)
mvec'
  {-# INLINE basicUnsafeCopy #-}
  basicUnsafeMove :: forall s. MVector s Ix2 -> MVector s Ix2 -> ST s ()
basicUnsafeMove (MV_Ix2 MVector s (Ix1, Ix1)
mvec) (MV_Ix2 MVector s (Ix1, Ix1)
mvec') = forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> ST s ()
VM.basicUnsafeMove MVector s (Ix1, Ix1)
mvec MVector s (Ix1, Ix1)
mvec'
  {-# INLINE basicUnsafeMove #-}
  basicUnsafeGrow :: forall s. MVector s Ix2 -> Ix1 -> ST s (MVector s Ix2)
basicUnsafeGrow (MV_Ix2 MVector s (Ix1, Ix1)
mvec) Ix1
len = forall s. MVector s (Ix1, Ix1) -> MVector s Ix2
MV_Ix2 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> Ix1 -> ST s (v s a)
VM.basicUnsafeGrow MVector s (Ix1, Ix1)
mvec Ix1
len
  {-# INLINE basicUnsafeGrow #-}
#if MIN_VERSION_vector(0,11,0)
  basicInitialize :: forall s. MVector s Ix2 -> ST s ()
basicInitialize (MV_Ix2 MVector s (Ix1, Ix1)
mvec) = forall (v :: * -> * -> *) a s. MVector v a => v s a -> ST s ()
VM.basicInitialize MVector s (Ix1, Ix1)
mvec
  {-# INLINE basicInitialize #-}
#endif

newtype instance VU.Vector Ix2 = V_Ix2 (VU.Vector (Int, Int))

instance V.Vector VU.Vector Ix2 where
  basicUnsafeFreeze :: forall s. Mutable Vector s Ix2 -> ST s (Vector Ix2)
basicUnsafeFreeze (MV_Ix2 MVector s (Ix1, Ix1)
mvec) = Vector (Ix1, Ix1) -> Vector Ix2
V_Ix2 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (v :: * -> *) a s. Vector v a => Mutable v s a -> ST s (v a)
V.basicUnsafeFreeze MVector s (Ix1, Ix1)
mvec
  {-# INLINE basicUnsafeFreeze #-}
  basicUnsafeThaw :: forall s. Vector Ix2 -> ST s (Mutable Vector s Ix2)
basicUnsafeThaw (V_Ix2 Vector (Ix1, Ix1)
vec) = forall s. MVector s (Ix1, Ix1) -> MVector s Ix2
MV_Ix2 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (v :: * -> *) a s. Vector v a => v a -> ST s (Mutable v s a)
V.basicUnsafeThaw Vector (Ix1, Ix1)
vec
  {-# INLINE basicUnsafeThaw #-}
  basicLength :: Vector Ix2 -> Ix1
basicLength (V_Ix2 Vector (Ix1, Ix1)
vec) = forall (v :: * -> *) a. Vector v a => v a -> Ix1
V.basicLength Vector (Ix1, Ix1)
vec
  {-# INLINE basicLength #-}
  basicUnsafeSlice :: Ix1 -> Ix1 -> Vector Ix2 -> Vector Ix2
basicUnsafeSlice Ix1
idx Ix1
len (V_Ix2 Vector (Ix1, Ix1)
vec) = Vector (Ix1, Ix1) -> Vector Ix2
V_Ix2 (forall (v :: * -> *) a. Vector v a => Ix1 -> Ix1 -> v a -> v a
V.basicUnsafeSlice Ix1
idx Ix1
len Vector (Ix1, Ix1)
vec)
  {-# INLINE basicUnsafeSlice #-}
  basicUnsafeIndexM :: Vector Ix2 -> Ix1 -> Box Ix2
basicUnsafeIndexM (V_Ix2 Vector (Ix1, Ix1)
vec) Ix1
idx = forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Ix1 -> Ix1 -> Ix2
(:.) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (v :: * -> *) a. Vector v a => v a -> Ix1 -> Box a
V.basicUnsafeIndexM Vector (Ix1, Ix1)
vec Ix1
idx
  {-# INLINE basicUnsafeIndexM #-}
  basicUnsafeCopy :: forall s. Mutable Vector s Ix2 -> Vector Ix2 -> ST s ()
basicUnsafeCopy (MV_Ix2 MVector s (Ix1, Ix1)
mvec) (V_Ix2 Vector (Ix1, Ix1)
vec) = forall (v :: * -> *) a s.
Vector v a =>
Mutable v s a -> v a -> ST s ()
V.basicUnsafeCopy MVector s (Ix1, Ix1)
mvec Vector (Ix1, Ix1)
vec
  {-# INLINE basicUnsafeCopy #-}
  elemseq :: forall b. Vector Ix2 -> Ix2 -> b -> b
elemseq Vector Ix2
_ = seq :: forall a b. a -> b -> b
seq
  {-# INLINE elemseq #-}

---- Unbox Ix

-- | Unboxing of a `IxN`.
instance (3 <= n, VU.Unbox (Ix (n - 1))) => VU.Unbox (IxN n)

newtype instance VU.MVector s (IxN n) = MV_IxN (VU.MVector s Int, VU.MVector s (Ix (n - 1)))

instance (3 <= n, VU.Unbox (Ix (n - 1))) => VM.MVector VU.MVector (IxN n) where
  basicLength :: forall s. MVector s (IxN n) -> Ix1
basicLength (MV_IxN (MVector s Ix1
_, MVector s (Ix (n - 1))
mvec)) = forall (v :: * -> * -> *) a s. MVector v a => v s a -> Ix1
VM.basicLength MVector s (Ix (n - 1))
mvec
  {-# INLINE basicLength #-}
  basicUnsafeSlice :: forall s. Ix1 -> Ix1 -> MVector s (IxN n) -> MVector s (IxN n)
basicUnsafeSlice Ix1
idx Ix1
len (MV_IxN (MVector s Ix1
mvec1, MVector s (Ix (n - 1))
mvec)) =
    forall s (n :: Natural).
(MVector s Ix1, MVector s (Ix (n - 1))) -> MVector s (IxN n)
MV_IxN (forall (v :: * -> * -> *) a s.
MVector v a =>
Ix1 -> Ix1 -> v s a -> v s a
VM.basicUnsafeSlice Ix1
idx Ix1
len MVector s Ix1
mvec1, forall (v :: * -> * -> *) a s.
MVector v a =>
Ix1 -> Ix1 -> v s a -> v s a
VM.basicUnsafeSlice Ix1
idx Ix1
len MVector s (Ix (n - 1))
mvec)
  {-# INLINE basicUnsafeSlice #-}
  basicOverlaps :: forall s. MVector s (IxN n) -> MVector s (IxN n) -> Bool
basicOverlaps (MV_IxN (MVector s Ix1
mvec1, MVector s (Ix (n - 1))
mvec)) (MV_IxN (MVector s Ix1
mvec1', MVector s (Ix (n - 1))
mvec')) =
    forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> Bool
VM.basicOverlaps MVector s Ix1
mvec1 MVector s Ix1
mvec1' Bool -> Bool -> Bool
&& forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> Bool
VM.basicOverlaps MVector s (Ix (n - 1))
mvec MVector s (Ix (n - 1))
mvec'
  {-# INLINE basicOverlaps #-}
  basicUnsafeNew :: forall s. Ix1 -> ST s (MVector s (IxN n))
basicUnsafeNew Ix1
len = do
    MVector s Ix1
iv <- forall (v :: * -> * -> *) a s. MVector v a => Ix1 -> ST s (v s a)
VM.basicUnsafeNew Ix1
len
    MVector s (Ix (n - 1))
ivs <- forall (v :: * -> * -> *) a s. MVector v a => Ix1 -> ST s (v s a)
VM.basicUnsafeNew Ix1
len
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s (n :: Natural).
(MVector s Ix1, MVector s (Ix (n - 1))) -> MVector s (IxN n)
MV_IxN (MVector s Ix1
iv, MVector s (Ix (n - 1))
ivs)
  {-# INLINE basicUnsafeNew #-}
  basicUnsafeReplicate :: forall s. Ix1 -> IxN n -> ST s (MVector s (IxN n))
basicUnsafeReplicate Ix1
len (Ix1
i :> Ix (n - 1)
ix) = do
    MVector s Ix1
iv <- forall (v :: * -> * -> *) a s.
MVector v a =>
Ix1 -> a -> ST s (v s a)
VM.basicUnsafeReplicate Ix1
len Ix1
i
    MVector s (Ix (n - 1))
ivs <- forall (v :: * -> * -> *) a s.
MVector v a =>
Ix1 -> a -> ST s (v s a)
VM.basicUnsafeReplicate Ix1
len Ix (n - 1)
ix
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s (n :: Natural).
(MVector s Ix1, MVector s (Ix (n - 1))) -> MVector s (IxN n)
MV_IxN (MVector s Ix1
iv, MVector s (Ix (n - 1))
ivs)
  {-# INLINE basicUnsafeReplicate #-}
  basicUnsafeRead :: forall s. MVector s (IxN n) -> Ix1 -> ST s (IxN n)
basicUnsafeRead (MV_IxN (MVector s Ix1
mvec1, MVector s (Ix (n - 1))
mvec)) Ix1
idx = do
    Ix1
i <- forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> Ix1 -> ST s a
VM.basicUnsafeRead MVector s Ix1
mvec1 Ix1
idx
    Ix (n - 1)
ix <- forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> Ix1 -> ST s a
VM.basicUnsafeRead MVector s (Ix (n - 1))
mvec Ix1
idx
    forall (m :: * -> *) a. Monad m => a -> m a
return (Ix1
i forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> Ix (n - 1)
ix)
  {-# INLINE basicUnsafeRead #-}
  basicUnsafeWrite :: forall s. MVector s (IxN n) -> Ix1 -> IxN n -> ST s ()
basicUnsafeWrite (MV_IxN (MVector s Ix1
mvec1, MVector s (Ix (n - 1))
mvec)) Ix1
idx (Ix1
i :> Ix (n - 1)
ix) = do
    forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> Ix1 -> a -> ST s ()
VM.basicUnsafeWrite MVector s Ix1
mvec1 Ix1
idx Ix1
i
    forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> Ix1 -> a -> ST s ()
VM.basicUnsafeWrite MVector s (Ix (n - 1))
mvec Ix1
idx Ix (n - 1)
ix
  {-# INLINE basicUnsafeWrite #-}
  basicClear :: forall s. MVector s (IxN n) -> ST s ()
basicClear (MV_IxN (MVector s Ix1
mvec1, MVector s (Ix (n - 1))
mvec)) = forall (v :: * -> * -> *) a s. MVector v a => v s a -> ST s ()
VM.basicClear MVector s Ix1
mvec1 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (v :: * -> * -> *) a s. MVector v a => v s a -> ST s ()
VM.basicClear MVector s (Ix (n - 1))
mvec
  {-# INLINE basicClear #-}
  basicSet :: forall s. MVector s (IxN n) -> IxN n -> ST s ()
basicSet (MV_IxN (MVector s Ix1
mvec1, MVector s (Ix (n - 1))
mvec)) (Ix1
i :> Ix (n - 1)
ix) = forall (v :: * -> * -> *) a s. MVector v a => v s a -> a -> ST s ()
VM.basicSet MVector s Ix1
mvec1 Ix1
i forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (v :: * -> * -> *) a s. MVector v a => v s a -> a -> ST s ()
VM.basicSet MVector s (Ix (n - 1))
mvec Ix (n - 1)
ix
  {-# INLINE basicSet #-}
  basicUnsafeCopy :: forall s. MVector s (IxN n) -> MVector s (IxN n) -> ST s ()
basicUnsafeCopy (MV_IxN (MVector s Ix1
mvec1, MVector s (Ix (n - 1))
mvec)) (MV_IxN (MVector s Ix1
mvec1', MVector s (Ix (n - 1))
mvec')) =
    forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> ST s ()
VM.basicUnsafeCopy MVector s Ix1
mvec1 MVector s Ix1
mvec1' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> ST s ()
VM.basicUnsafeCopy MVector s (Ix (n - 1))
mvec MVector s (Ix (n - 1))
mvec'
  {-# INLINE basicUnsafeCopy #-}
  basicUnsafeMove :: forall s. MVector s (IxN n) -> MVector s (IxN n) -> ST s ()
basicUnsafeMove (MV_IxN (MVector s Ix1
mvec1, MVector s (Ix (n - 1))
mvec)) (MV_IxN (MVector s Ix1
mvec1', MVector s (Ix (n - 1))
mvec')) =
    forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> ST s ()
VM.basicUnsafeMove MVector s Ix1
mvec1 MVector s Ix1
mvec1' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> ST s ()
VM.basicUnsafeMove MVector s (Ix (n - 1))
mvec MVector s (Ix (n - 1))
mvec'
  {-# INLINE basicUnsafeMove #-}
  basicUnsafeGrow :: forall s. MVector s (IxN n) -> Ix1 -> ST s (MVector s (IxN n))
basicUnsafeGrow (MV_IxN (MVector s Ix1
mvec1, MVector s (Ix (n - 1))
mvec)) Ix1
len = do
    MVector s Ix1
iv <- forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> Ix1 -> ST s (v s a)
VM.basicUnsafeGrow MVector s Ix1
mvec1 Ix1
len
    MVector s (Ix (n - 1))
ivs <- forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> Ix1 -> ST s (v s a)
VM.basicUnsafeGrow MVector s (Ix (n - 1))
mvec Ix1
len
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s (n :: Natural).
(MVector s Ix1, MVector s (Ix (n - 1))) -> MVector s (IxN n)
MV_IxN (MVector s Ix1
iv, MVector s (Ix (n - 1))
ivs)
  {-# INLINE basicUnsafeGrow #-}
#if MIN_VERSION_vector(0,11,0)
  basicInitialize :: forall s. MVector s (IxN n) -> ST s ()
basicInitialize (MV_IxN (MVector s Ix1
mvec1, MVector s (Ix (n - 1))
mvec)) =
    forall (v :: * -> * -> *) a s. MVector v a => v s a -> ST s ()
VM.basicInitialize MVector s Ix1
mvec1 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (v :: * -> * -> *) a s. MVector v a => v s a -> ST s ()
VM.basicInitialize MVector s (Ix (n - 1))
mvec
  {-# INLINE basicInitialize #-}
#endif

newtype instance VU.Vector (IxN n) = V_IxN (VU.Vector Int, VU.Vector (Ix (n - 1)))

instance (3 <= n, VU.Unbox (Ix (n - 1))) => V.Vector VU.Vector (IxN n) where
  basicUnsafeFreeze :: forall s. Mutable Vector s (IxN n) -> ST s (Vector (IxN n))
basicUnsafeFreeze (MV_IxN (MVector s Ix1
mvec1, MVector s (Ix (n - 1))
mvec)) = do
    Vector Ix1
iv <- forall (v :: * -> *) a s. Vector v a => Mutable v s a -> ST s (v a)
V.basicUnsafeFreeze MVector s Ix1
mvec1
    Vector (Ix (n - 1))
ivs <- forall (v :: * -> *) a s. Vector v a => Mutable v s a -> ST s (v a)
V.basicUnsafeFreeze MVector s (Ix (n - 1))
mvec
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (n :: Natural).
(Vector Ix1, Vector (Ix (n - 1))) -> Vector (IxN n)
V_IxN (Vector Ix1
iv, Vector (Ix (n - 1))
ivs)
  {-# INLINE basicUnsafeFreeze #-}
  basicUnsafeThaw :: forall s. Vector (IxN n) -> ST s (Mutable Vector s (IxN n))
basicUnsafeThaw (V_IxN (Vector Ix1
vec1, Vector (Ix (n - 1))
vec)) = do
    MVector s Ix1
imv <- forall (v :: * -> *) a s. Vector v a => v a -> ST s (Mutable v s a)
V.basicUnsafeThaw Vector Ix1
vec1
    MVector s (Ix (n - 1))
imvs <- forall (v :: * -> *) a s. Vector v a => v a -> ST s (Mutable v s a)
V.basicUnsafeThaw Vector (Ix (n - 1))
vec
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s (n :: Natural).
(MVector s Ix1, MVector s (Ix (n - 1))) -> MVector s (IxN n)
MV_IxN (MVector s Ix1
imv, MVector s (Ix (n - 1))
imvs)
  {-# INLINE basicUnsafeThaw #-}
  basicLength :: Vector (IxN n) -> Ix1
basicLength (V_IxN (Vector Ix1
_, Vector (Ix (n - 1))
vec)) = forall (v :: * -> *) a. Vector v a => v a -> Ix1
V.basicLength Vector (Ix (n - 1))
vec
  {-# INLINE basicLength #-}
  basicUnsafeSlice :: Ix1 -> Ix1 -> Vector (IxN n) -> Vector (IxN n)
basicUnsafeSlice Ix1
idx Ix1
len (V_IxN (Vector Ix1
vec1, Vector (Ix (n - 1))
vec)) =
    forall (n :: Natural).
(Vector Ix1, Vector (Ix (n - 1))) -> Vector (IxN n)
V_IxN (forall (v :: * -> *) a. Vector v a => Ix1 -> Ix1 -> v a -> v a
V.basicUnsafeSlice Ix1
idx Ix1
len Vector Ix1
vec1, forall (v :: * -> *) a. Vector v a => Ix1 -> Ix1 -> v a -> v a
V.basicUnsafeSlice Ix1
idx Ix1
len Vector (Ix (n - 1))
vec)
  {-# INLINE basicUnsafeSlice #-}
  basicUnsafeIndexM :: Vector (IxN n) -> Ix1 -> Box (IxN n)
basicUnsafeIndexM (V_IxN (Vector Ix1
vec1, Vector (Ix (n - 1))
vec)) Ix1
idx = do
    Ix1
i <- forall (v :: * -> *) a. Vector v a => v a -> Ix1 -> Box a
V.basicUnsafeIndexM Vector Ix1
vec1 Ix1
idx
    Ix (n - 1)
ix <- forall (v :: * -> *) a. Vector v a => v a -> Ix1 -> Box a
V.basicUnsafeIndexM Vector (Ix (n - 1))
vec Ix1
idx
    forall (m :: * -> *) a. Monad m => a -> m a
return (Ix1
i forall (n :: Natural). Ix1 -> Ix (n - 1) -> IxN n
:> Ix (n - 1)
ix)
  {-# INLINE basicUnsafeIndexM #-}
  basicUnsafeCopy :: forall s. Mutable Vector s (IxN n) -> Vector (IxN n) -> ST s ()
basicUnsafeCopy (MV_IxN (MVector s Ix1
mvec1, MVector s (Ix (n - 1))
mvec)) (V_IxN (Vector Ix1
vec1, Vector (Ix (n - 1))
vec)) =
    forall (v :: * -> *) a s.
Vector v a =>
Mutable v s a -> v a -> ST s ()
V.basicUnsafeCopy MVector s Ix1
mvec1 Vector Ix1
vec1 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (v :: * -> *) a s.
Vector v a =>
Mutable v s a -> v a -> ST s ()
V.basicUnsafeCopy MVector s (Ix (n - 1))
mvec Vector (Ix (n - 1))
vec
  {-# INLINE basicUnsafeCopy #-}
  elemseq :: forall b. Vector (IxN n) -> IxN n -> b -> b
elemseq Vector (IxN n)
_ = seq :: forall a b. a -> b -> b
seq
  {-# INLINE elemseq #-}