{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MagicHash #-}

module Country.Unexposed.Util
  ( mapTextArray
  , charToWord8
  , word16ToChar
  , word16ToInt
  , timesTwo
  , timesThree
  , half
  ) where

import Data.Bits (unsafeShiftL,unsafeShiftR)
import Data.Char (chr,ord)
import Data.Word (Word8,Word16)
import GHC.Exts (sizeofByteArray#)
import GHC.Int (Int(I#))

import qualified Data.Text.Array as TA


mapTextArray :: (Char -> Char) -> TA.Array -> TA.Array
mapTextArray :: (Char -> Char) -> Array -> Array
mapTextArray Char -> Char
f a :: Array
a@(TA.ByteArray ByteArray#
inner) = (forall s. ST s (MArray s)) -> Array
TA.run forall a b. (a -> b) -> a -> b
$ do
  let len :: Int
len = Int# -> Int
I# (ByteArray# -> Int#
sizeofByteArray# ByteArray#
inner)
  MArray s
m <- forall s. Int -> ST s (MArray s)
TA.new Int
len
  forall s. Int -> MArray s -> Int -> Array -> Int -> ST s ()
TA.copyI Int
len MArray s
m Int
0 Array
a Int
0
  let go :: Int -> ST s ()
go !Int
ix = if Int
ix forall a. Ord a => a -> a -> Bool
< Int
len
        then do
          forall s. MArray s -> Int -> Word8 -> ST s ()
TA.unsafeWrite MArray s
m Int
ix (Char -> Word8
charToWord8 (Char -> Char
f (Word8 -> Char
word8ToChar (Array -> Int -> Word8
TA.unsafeIndex Array
a Int
ix))))
          Int -> ST s ()
go (Int
ix forall a. Num a => a -> a -> a
+ Int
1)
        else forall (m :: * -> *) a. Monad m => a -> m a
return ()
  Int -> ST s ()
go Int
0
  forall (m :: * -> *) a. Monad m => a -> m a
return MArray s
m
{-# INLINE mapTextArray #-}

charToWord8 :: Char -> Word8
charToWord8 :: Char -> Word8
charToWord8 = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Int
ord
{-# INLINE charToWord8 #-}

word8ToChar :: Word8 -> Char
word8ToChar :: Word8 -> Char
word8ToChar = Int -> Char
chr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral
{-# INLINE word8ToChar #-}

word16ToChar :: Word16 -> Char
word16ToChar :: Word16 -> Char
word16ToChar = Int -> Char
chr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral
{-# INLINE word16ToChar #-}

word16ToInt :: Word16 -> Int
word16ToInt :: Word16 -> Int
word16ToInt = forall a b. (Integral a, Num b) => a -> b
fromIntegral
{-# INLINE word16ToInt #-}

timesTwo :: Int -> Int
timesTwo :: Int -> Int
timesTwo Int
x = forall a. Bits a => a -> Int -> a
unsafeShiftL Int
x Int
1
{-# INLINE timesTwo #-}

timesThree :: Int -> Int
timesThree :: Int -> Int
timesThree Int
x = Int
x forall a. Num a => a -> a -> a
+ Int -> Int
timesTwo Int
x
{-# INLINE timesThree #-}

half :: Int -> Int
half :: Int -> Int
half Int
x = forall a. Bits a => a -> Int -> a
unsafeShiftR Int
x Int
1
{-# INLINE half #-}