{-# LANGUAGE CPP #-}
module Data.Vector.Algorithms.Optimal
( sort2ByIndex
, sort2ByOffset
, sort3ByIndex
, sort3ByOffset
, sort4ByIndex
, sort4ByOffset
, Comparison
) where
import Prelude hiding (read, length)
import Control.Monad.Primitive
import Data.Vector.Generic.Mutable
import Data.Vector.Algorithms.Common (Comparison)
#include "vector.h"
sort2ByOffset :: (PrimMonad m, MVector v e)
=> Comparison e -> v (PrimState m) e -> Int -> m ()
sort2ByOffset cmp a off = sort2ByIndex cmp a off (off + 1)
{-# INLINABLE sort2ByOffset #-}
sort2ByIndex :: (PrimMonad m, MVector v e)
=> Comparison e -> v (PrimState m) e -> Int -> Int -> m ()
sort2ByIndex cmp a i j = UNSAFE_CHECK(checkIndex) "sort2ByIndex" i (length a)
$ UNSAFE_CHECK(checkIndex) "sort2ByIndex" j (length a) $ do
a0 <- unsafeRead a i
a1 <- unsafeRead a j
case cmp a0 a1 of
GT -> unsafeWrite a i a1 >> unsafeWrite a j a0
_ -> return ()
{-# INLINABLE sort2ByIndex #-}
sort3ByOffset :: (PrimMonad m, MVector v e)
=> Comparison e -> v (PrimState m) e -> Int -> m ()
sort3ByOffset cmp a off = sort3ByIndex cmp a off (off + 1) (off + 2)
{-# INLINABLE sort3ByOffset #-}
sort3ByIndex :: (PrimMonad m, MVector v e)
=> Comparison e -> v (PrimState m) e -> Int -> Int -> Int -> m ()
sort3ByIndex cmp a i j k = UNSAFE_CHECK(checkIndex) "sort3ByIndex" i (length a)
$ UNSAFE_CHECK(checkIndex) "sort3ByIndex" j (length a)
$ UNSAFE_CHECK(checkIndex) "sort3ByIndex" k (length a) $ do
a0 <- unsafeRead a i
a1 <- unsafeRead a j
a2 <- unsafeRead a k
case cmp a0 a1 of
GT -> case cmp a0 a2 of
GT -> case cmp a2 a1 of
LT -> do unsafeWrite a i a2
unsafeWrite a k a0
_ -> do unsafeWrite a i a1
unsafeWrite a j a2
unsafeWrite a k a0
_ -> do unsafeWrite a i a1
unsafeWrite a j a0
_ -> case cmp a1 a2 of
GT -> case cmp a0 a2 of
GT -> do unsafeWrite a i a2
unsafeWrite a j a0
unsafeWrite a k a1
_ -> do unsafeWrite a j a2
unsafeWrite a k a1
_ -> return ()
{-# INLINABLE sort3ByIndex #-}
sort4ByOffset :: (PrimMonad m, MVector v e)
=> Comparison e -> v (PrimState m) e -> Int -> m ()
sort4ByOffset cmp a off = sort4ByIndex cmp a off (off + 1) (off + 2) (off + 3)
{-# INLINABLE sort4ByOffset #-}
sort4ByIndex :: (PrimMonad m, MVector v e)
=> Comparison e -> v (PrimState m) e -> Int -> Int -> Int -> Int -> m ()
sort4ByIndex cmp a i j k l = UNSAFE_CHECK(checkIndex) "sort4ByIndex" i (length a)
$ UNSAFE_CHECK(checkIndex) "sort4ByIndex" j (length a)
$ UNSAFE_CHECK(checkIndex) "sort4ByIndex" k (length a)
$ UNSAFE_CHECK(checkIndex) "sort4ByIndex" l (length a) $ do
a0 <- unsafeRead a i
a1 <- unsafeRead a j
a2 <- unsafeRead a k
a3 <- unsafeRead a l
case cmp a0 a1 of
GT -> case cmp a0 a2 of
GT -> case cmp a1 a2 of
GT -> case cmp a1 a3 of
GT -> case cmp a2 a3 of
GT -> do unsafeWrite a i a3
unsafeWrite a j a2
unsafeWrite a k a1
unsafeWrite a l a0
_ -> do unsafeWrite a i a2
unsafeWrite a j a3
unsafeWrite a k a1
unsafeWrite a l a0
_ -> case cmp a0 a3 of
GT -> do unsafeWrite a i a2
unsafeWrite a j a1
unsafeWrite a k a3
unsafeWrite a l a0
_ -> do unsafeWrite a i a2
unsafeWrite a j a1
unsafeWrite a k a0
unsafeWrite a l a3
_ -> case cmp a2 a3 of
GT -> case cmp a1 a3 of
GT -> do unsafeWrite a i a3
unsafeWrite a j a1
unsafeWrite a k a2
unsafeWrite a l a0
_ -> do unsafeWrite a i a1
unsafeWrite a j a3
unsafeWrite a k a2
unsafeWrite a l a0
_ -> case cmp a0 a3 of
GT -> do unsafeWrite a i a1
unsafeWrite a j a2
unsafeWrite a k a3
unsafeWrite a l a0
_ -> do unsafeWrite a i a1
unsafeWrite a j a2
unsafeWrite a k a0
_ -> case cmp a0 a3 of
GT -> case cmp a1 a3 of
GT -> do unsafeWrite a i a3
unsafeWrite a k a0
unsafeWrite a l a2
_ -> do unsafeWrite a i a1
unsafeWrite a j a3
unsafeWrite a k a0
unsafeWrite a l a2
_ -> case cmp a2 a3 of
GT -> do unsafeWrite a i a1
unsafeWrite a j a0
unsafeWrite a k a3
unsafeWrite a l a2
_ -> do unsafeWrite a i a1
unsafeWrite a j a0
_ -> case cmp a1 a2 of
GT -> case cmp a0 a2 of
GT -> case cmp a0 a3 of
GT -> case cmp a2 a3 of
GT -> do unsafeWrite a i a3
unsafeWrite a j a2
unsafeWrite a k a0
unsafeWrite a l a1
_ -> do unsafeWrite a i a2
unsafeWrite a j a3
unsafeWrite a k a0
unsafeWrite a l a1
_ -> case cmp a1 a3 of
GT -> do unsafeWrite a i a2
unsafeWrite a j a0
unsafeWrite a k a3
unsafeWrite a l a1
_ -> do unsafeWrite a i a2
unsafeWrite a j a0
unsafeWrite a k a1
_ -> case cmp a2 a3 of
GT -> case cmp a0 a3 of
GT -> do unsafeWrite a i a3
unsafeWrite a j a0
unsafeWrite a l a1
_ -> do
unsafeWrite a j a3
unsafeWrite a l a1
_ -> case cmp a1 a3 of
GT -> do
unsafeWrite a j a2
unsafeWrite a k a3
unsafeWrite a l a1
_ -> do
unsafeWrite a j a2
unsafeWrite a k a1
_ -> case cmp a1 a3 of
GT -> case cmp a0 a3 of
GT -> do unsafeWrite a i a3
unsafeWrite a j a0
unsafeWrite a k a1
unsafeWrite a l a2
_ -> do
unsafeWrite a j a3
unsafeWrite a k a1
unsafeWrite a l a2
_ -> case cmp a2 a3 of
GT -> do
unsafeWrite a k a3
unsafeWrite a l a2
_ -> do
return ()
{-# INLINABLE sort4ByIndex #-}