    -- |
    -- Module      : Basement.String.Encoding.UTF32
    -- License     : BSD-style
    -- Maintainer  : Foundation
    -- Stability   : experimental
    -- Portability : portable
    --
    {-# LANGUAGE MagicHash #-}
    module Basement.String.Encoding.UTF32
        ( UTF32(..)
        , UTF32_Invalid
        ) where

    import GHC.Prim
    import GHC.Word
    import GHC.Types
    import Basement.Compat.Base
    import Basement.Types.OffsetSize
    import Basement.Monad
    import Basement.Numerical.Additive
    import Basement.UArray
    import Basement.UArray.Mutable (MUArray)
    import Basement.MutableBuilder

    import Basement.String.Encoding.Encoding

    data UTF32 = UTF32

    data UTF32_Invalid = UTF32_Invalid
      deriving (Typeable, Int -> UTF32_Invalid -> ShowS
    [UTF32_Invalid] -> ShowS
    UTF32_Invalid -> String
    (Int -> UTF32_Invalid -> ShowS)
    -> (UTF32_Invalid -> String)
    -> ([UTF32_Invalid] -> ShowS)
    -> Show UTF32_Invalid
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [UTF32_Invalid] -> ShowS
    $cshowList :: [UTF32_Invalid] -> ShowS
    show :: UTF32_Invalid -> String
    $cshow :: UTF32_Invalid -> String
    showsPrec :: Int -> UTF32_Invalid -> ShowS
    $cshowsPrec :: Int -> UTF32_Invalid -> ShowS
    Show, UTF32_Invalid -> UTF32_Invalid -> Bool
    (UTF32_Invalid -> UTF32_Invalid -> Bool)
    -> (UTF32_Invalid -> UTF32_Invalid -> Bool) -> Eq UTF32_Invalid
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: UTF32_Invalid -> UTF32_Invalid -> Bool
    $c/= :: UTF32_Invalid -> UTF32_Invalid -> Bool
    == :: UTF32_Invalid -> UTF32_Invalid -> Bool
    $c== :: UTF32_Invalid -> UTF32_Invalid -> Bool
    Eq, Eq UTF32_Invalid
    Eq UTF32_Invalid =>
    (UTF32_Invalid -> UTF32_Invalid -> Ordering)
    -> (UTF32_Invalid -> UTF32_Invalid -> Bool)
    -> (UTF32_Invalid -> UTF32_Invalid -> Bool)
    -> (UTF32_Invalid -> UTF32_Invalid -> Bool)
    -> (UTF32_Invalid -> UTF32_Invalid -> Bool)
    -> (UTF32_Invalid -> UTF32_Invalid -> UTF32_Invalid)
    -> (UTF32_Invalid -> UTF32_Invalid -> UTF32_Invalid)
    -> Ord UTF32_Invalid
    UTF32_Invalid -> UTF32_Invalid -> Bool
    UTF32_Invalid -> UTF32_Invalid -> Ordering
    UTF32_Invalid -> UTF32_Invalid -> UTF32_Invalid
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    min :: UTF32_Invalid -> UTF32_Invalid -> UTF32_Invalid
    $cmin :: UTF32_Invalid -> UTF32_Invalid -> UTF32_Invalid
    max :: UTF32_Invalid -> UTF32_Invalid -> UTF32_Invalid
    $cmax :: UTF32_Invalid -> UTF32_Invalid -> UTF32_Invalid
    >= :: UTF32_Invalid -> UTF32_Invalid -> Bool
    $c>= :: UTF32_Invalid -> UTF32_Invalid -> Bool
    > :: UTF32_Invalid -> UTF32_Invalid -> Bool
    $c> :: UTF32_Invalid -> UTF32_Invalid -> Bool
    <= :: UTF32_Invalid -> UTF32_Invalid -> Bool
    $c<= :: UTF32_Invalid -> UTF32_Invalid -> Bool
    < :: UTF32_Invalid -> UTF32_Invalid -> Bool
    $c< :: UTF32_Invalid -> UTF32_Invalid -> Bool
    compare :: UTF32_Invalid -> UTF32_Invalid -> Ordering
    $ccompare :: UTF32_Invalid -> UTF32_Invalid -> Ordering
    $cp1Ord :: Eq UTF32_Invalid
    Ord, Int -> UTF32_Invalid
    UTF32_Invalid -> Int
    UTF32_Invalid -> [UTF32_Invalid]
    UTF32_Invalid -> UTF32_Invalid
    UTF32_Invalid -> UTF32_Invalid -> [UTF32_Invalid]
    UTF32_Invalid -> UTF32_Invalid -> UTF32_Invalid -> [UTF32_Invalid]
    (UTF32_Invalid -> UTF32_Invalid)
    -> (UTF32_Invalid -> UTF32_Invalid)
    -> (Int -> UTF32_Invalid)
    -> (UTF32_Invalid -> Int)
    -> (UTF32_Invalid -> [UTF32_Invalid])
    -> (UTF32_Invalid -> UTF32_Invalid -> [UTF32_Invalid])
    -> (UTF32_Invalid -> UTF32_Invalid -> [UTF32_Invalid])
    -> (UTF32_Invalid
        -> UTF32_Invalid -> UTF32_Invalid -> [UTF32_Invalid])
    -> Enum UTF32_Invalid
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    enumFromThenTo :: UTF32_Invalid -> UTF32_Invalid -> UTF32_Invalid -> [UTF32_Invalid]
    $cenumFromThenTo :: UTF32_Invalid -> UTF32_Invalid -> UTF32_Invalid -> [UTF32_Invalid]
    enumFromTo :: UTF32_Invalid -> UTF32_Invalid -> [UTF32_Invalid]
    $cenumFromTo :: UTF32_Invalid -> UTF32_Invalid -> [UTF32_Invalid]
    enumFromThen :: UTF32_Invalid -> UTF32_Invalid -> [UTF32_Invalid]
    $cenumFromThen :: UTF32_Invalid -> UTF32_Invalid -> [UTF32_Invalid]
    enumFrom :: UTF32_Invalid -> [UTF32_Invalid]
    $cenumFrom :: UTF32_Invalid -> [UTF32_Invalid]
    fromEnum :: UTF32_Invalid -> Int
    $cfromEnum :: UTF32_Invalid -> Int
    toEnum :: Int -> UTF32_Invalid
    $ctoEnum :: Int -> UTF32_Invalid
    pred :: UTF32_Invalid -> UTF32_Invalid
    $cpred :: UTF32_Invalid -> UTF32_Invalid
    succ :: UTF32_Invalid -> UTF32_Invalid
    $csucc :: UTF32_Invalid -> UTF32_Invalid
    Enum, UTF32_Invalid
    UTF32_Invalid -> UTF32_Invalid -> Bounded UTF32_Invalid
    forall a. a -> a -> Bounded a
    maxBound :: UTF32_Invalid
    $cmaxBound :: UTF32_Invalid
    minBound :: UTF32_Invalid
    $cminBound :: UTF32_Invalid
    Bounded)
    instance Exception UTF32_Invalid

    instance Encoding UTF32 where
        type Unit UTF32 = Word32
        type Error UTF32 = UTF32_Invalid
        encodingNext :: UTF32
    -> (Offset (Unit UTF32) -> Unit UTF32)
    -> Offset (Unit UTF32)
    -> Either (Error UTF32) (Char, Offset (Unit UTF32))
    encodingNext  _ = (Offset Word32 -> Word32)
    -> Offset Word32 -> Either UTF32_Invalid (Char, Offset Word32)
    (Offset (Unit UTF32) -> Unit UTF32)
    -> Offset (Unit UTF32)
    -> Either (Error UTF32) (Char, Offset (Unit UTF32))
    next
        encodingWrite :: UTF32
    -> Char
    -> Builder
         (UArray (Unit UTF32)) (MUArray (Unit UTF32)) (Unit UTF32) st err ()
    encodingWrite _ = Char
    -> Builder
         (UArray (Unit UTF32)) (MUArray (Unit UTF32)) (Unit UTF32) st err ()
    forall (st :: * -> *) err.
    (PrimMonad st, Monad st) =>
    Char -> Builder (UArray Word32) (MUArray Word32) Word32 st err ()
    write

    next :: (Offset Word32 -> Word32)
         -> Offset Word32
         -> Either UTF32_Invalid (Char, Offset Word32)
    next :: (Offset Word32 -> Word32)
    -> Offset Word32 -> Either UTF32_Invalid (Char, Offset Word32)
    next getter :: Offset Word32 -> Word32
    getter off :: Offset Word32
    off = (Char, Offset Word32) -> Either UTF32_Invalid (Char, Offset Word32)
    forall a b. b -> Either a b
    Right (Char
    char, Offset Word32
    off Offset Word32 -> Offset Word32 -> Offset Word32
    forall a. Additive a => a -> a -> a
    + Int -> Offset Word32
    forall ty. Int -> Offset ty
    Offset 1)
      where
        !(W32# hh :: Word#
    hh) = Offset Word32 -> Word32
    getter Offset Word32
    off
        char :: Char
        char :: Char
    char = Char# -> Char
    C# (Int# -> Char#
    chr# (Word# -> Int#
    word2Int# Word#
    hh))

    write :: (PrimMonad st, Monad st)
          => Char
          -> Builder (UArray Word32) (MUArray Word32) Word32 st err ()
    write :: Char -> Builder (UArray Word32) (MUArray Word32) Word32 st err ()
    write c :: Char
    c = Word32 -> Builder (UArray Word32) (MUArray Word32) Word32 st err ()
    forall ty (state :: * -> *) err.
    (PrimType ty, PrimMonad state) =>
    ty -> Builder (UArray ty) (MUArray ty) ty state err ()
    builderAppend Word32
    w32
      where
        !(C# ch :: Char#
    ch) = Char
    c
        w32 :: Word32
        w32 :: Word32
    w32 = Word# -> Word32
    W32# (Int# -> Word#
    int2Word# (Char# -> Int#
    ord# Char#
    ch))