    {-# LINE 1 "Data/Text/ICU/Collate.hsc" #-}
    {-# LANGUAGE BangPatterns, CPP, DeriveDataTypeable, ForeignFunctionInterface #-}
    -- |
    -- Module      : Data.Text.ICU.Collate
    -- Copyright   : (c) 2010 Bryan O'Sullivan
    --
    -- License     : BSD-style
    -- Maintainer  : bos@serpentine.com
    -- Stability   : experimental
    -- Portability : GHC
    --
    -- String collation functions for Unicode, implemented as bindings to
    -- the International Components for Unicode (ICU) libraries.

    module Data.Text.ICU.Collate
        (
        -- * Unicode collation API
        -- $api
        -- * Types
          MCollator
        , Attribute(..)
        , AlternateHandling(..)
        , CaseFirst(..)
        , Strength(..)
        -- * Functions
        , open
        , openRules
        , collate
        , collateIter
        -- ** Utility functions
        , getRules
        , getAttribute
        , setAttribute
        , sortKey
        , clone
        , freeze
        ) where

    import Control.DeepSeq (NFData(..))
    import Data.ByteString (empty)
    import Data.ByteString.Internal (ByteString(..), create, mallocByteString,
                                     memcpy)
    import Data.Int (Int32)
    import Data.Text (Text)
    import qualified Data.Text as T
    import Data.Text.Foreign (useAsPtr)
    import Data.Text.ICU.Collate.Internal (Collator(..), MCollator, UCollator,
                                           withCollator, wrap)
    import Data.Text.ICU.Error (u_INVALID_FORMAT_ERROR)
    import Data.Text.ICU.Error.Internal (UErrorCode, UParseError, handleError, handleParseError)
    import Data.Text.ICU.Internal
        (LocaleName, UChar, CharIterator, UCharIterator,
         asOrdering, fromUCharPtr, withCharIterator, withLocaleName, useAsUCharPtr)
    import Data.Typeable (Typeable)
    import Data.Word (Word8)
    import Foreign.C.String (CString)
    import Foreign.C.Types (CInt(..))
    import Foreign.ForeignPtr (withForeignPtr)
    import Foreign.Marshal.Alloc (alloca)
    import Foreign.Marshal.Utils (with)
    import Foreign.Ptr (Ptr, nullPtr)
    import Foreign.Storable (peek)

    -- $api
    --

    -- | Control the handling of variable weight elements.
    data AlternateHandling = NonIgnorable
                           -- ^ Treat all codepoints with non-ignorable primary
                           -- weights in the same way.
                           | Shifted
                             -- ^ Cause codepoints with primary weights that are
                             -- equal to or below the variable top value to be
                             -- ignored on primary level and moved to the
                             -- quaternary level.
                             deriving (AlternateHandling -> AlternateHandling -> Bool
    (AlternateHandling -> AlternateHandling -> Bool)
    -> (AlternateHandling -> AlternateHandling -> Bool)
    -> Eq AlternateHandling
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: AlternateHandling -> AlternateHandling -> Bool
    == :: AlternateHandling -> AlternateHandling -> Bool
    $c/= :: AlternateHandling -> AlternateHandling -> Bool
    /= :: AlternateHandling -> AlternateHandling -> Bool
    Eq, AlternateHandling
    AlternateHandling -> AlternateHandling -> Bounded AlternateHandling
    forall a. a -> a -> Bounded a
    $cminBound :: AlternateHandling
    minBound :: AlternateHandling
    $cmaxBound :: AlternateHandling
    maxBound :: AlternateHandling
    Bounded, Int -> AlternateHandling
    AlternateHandling -> Int
    AlternateHandling -> [AlternateHandling]
    AlternateHandling -> AlternateHandling
    AlternateHandling -> AlternateHandling -> [AlternateHandling]
    AlternateHandling
    -> AlternateHandling -> AlternateHandling -> [AlternateHandling]
    (AlternateHandling -> AlternateHandling)
    -> (AlternateHandling -> AlternateHandling)
    -> (Int -> AlternateHandling)
    -> (AlternateHandling -> Int)
    -> (AlternateHandling -> [AlternateHandling])
    -> (AlternateHandling -> AlternateHandling -> [AlternateHandling])
    -> (AlternateHandling -> AlternateHandling -> [AlternateHandling])
    -> (AlternateHandling
        -> AlternateHandling -> AlternateHandling -> [AlternateHandling])
    -> Enum AlternateHandling
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: AlternateHandling -> AlternateHandling
    succ :: AlternateHandling -> AlternateHandling
    $cpred :: AlternateHandling -> AlternateHandling
    pred :: AlternateHandling -> AlternateHandling
    $ctoEnum :: Int -> AlternateHandling
    toEnum :: Int -> AlternateHandling
    $cfromEnum :: AlternateHandling -> Int
    fromEnum :: AlternateHandling -> Int
    $cenumFrom :: AlternateHandling -> [AlternateHandling]
    enumFrom :: AlternateHandling -> [AlternateHandling]
    $cenumFromThen :: AlternateHandling -> AlternateHandling -> [AlternateHandling]
    enumFromThen :: AlternateHandling -> AlternateHandling -> [AlternateHandling]
    $cenumFromTo :: AlternateHandling -> AlternateHandling -> [AlternateHandling]
    enumFromTo :: AlternateHandling -> AlternateHandling -> [AlternateHandling]
    $cenumFromThenTo :: AlternateHandling
    -> AlternateHandling -> AlternateHandling -> [AlternateHandling]
    enumFromThenTo :: AlternateHandling
    -> AlternateHandling -> AlternateHandling -> [AlternateHandling]
    Enum, Int -> AlternateHandling -> ShowS
    [AlternateHandling] -> ShowS
    AlternateHandling -> String
    (Int -> AlternateHandling -> ShowS)
    -> (AlternateHandling -> String)
    -> ([AlternateHandling] -> ShowS)
    -> Show AlternateHandling
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> AlternateHandling -> ShowS
    showsPrec :: Int -> AlternateHandling -> ShowS
    $cshow :: AlternateHandling -> String
    show :: AlternateHandling -> String
    $cshowList :: [AlternateHandling] -> ShowS
    showList :: [AlternateHandling] -> ShowS
    Show, Typeable)

    instance NFData AlternateHandling where
        rnf :: AlternateHandling -> ()
    rnf !AlternateHandling
    _ = ()

    -- | Control the ordering of upper and lower case letters.
    data CaseFirst = UpperFirst     -- ^ Force upper case letters to sort before
                                    -- lower case.
                   | LowerFirst     -- ^ Force lower case letters to sort before
                                    -- upper case.
                    deriving (CaseFirst -> CaseFirst -> Bool
    (CaseFirst -> CaseFirst -> Bool)
    -> (CaseFirst -> CaseFirst -> Bool) -> Eq CaseFirst
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: CaseFirst -> CaseFirst -> Bool
    == :: CaseFirst -> CaseFirst -> Bool
    $c/= :: CaseFirst -> CaseFirst -> Bool
    /= :: CaseFirst -> CaseFirst -> Bool
    Eq, CaseFirst
    CaseFirst -> CaseFirst -> Bounded CaseFirst
    forall a. a -> a -> Bounded a
    $cminBound :: CaseFirst
    minBound :: CaseFirst
    $cmaxBound :: CaseFirst
    maxBound :: CaseFirst
    Bounded, Int -> CaseFirst
    CaseFirst -> Int
    CaseFirst -> [CaseFirst]
    CaseFirst -> CaseFirst
    CaseFirst -> CaseFirst -> [CaseFirst]
    CaseFirst -> CaseFirst -> CaseFirst -> [CaseFirst]
    (CaseFirst -> CaseFirst)
    -> (CaseFirst -> CaseFirst)
    -> (Int -> CaseFirst)
    -> (CaseFirst -> Int)
    -> (CaseFirst -> [CaseFirst])
    -> (CaseFirst -> CaseFirst -> [CaseFirst])
    -> (CaseFirst -> CaseFirst -> [CaseFirst])
    -> (CaseFirst -> CaseFirst -> CaseFirst -> [CaseFirst])
    -> Enum CaseFirst
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: CaseFirst -> CaseFirst
    succ :: CaseFirst -> CaseFirst
    $cpred :: CaseFirst -> CaseFirst
    pred :: CaseFirst -> CaseFirst
    $ctoEnum :: Int -> CaseFirst
    toEnum :: Int -> CaseFirst
    $cfromEnum :: CaseFirst -> Int
    fromEnum :: CaseFirst -> Int
    $cenumFrom :: CaseFirst -> [CaseFirst]
    enumFrom :: CaseFirst -> [CaseFirst]
    $cenumFromThen :: CaseFirst -> CaseFirst -> [CaseFirst]
    enumFromThen :: CaseFirst -> CaseFirst -> [CaseFirst]
    $cenumFromTo :: CaseFirst -> CaseFirst -> [CaseFirst]
    enumFromTo :: CaseFirst -> CaseFirst -> [CaseFirst]
    $cenumFromThenTo :: CaseFirst -> CaseFirst -> CaseFirst -> [CaseFirst]
    enumFromThenTo :: CaseFirst -> CaseFirst -> CaseFirst -> [CaseFirst]
    Enum, Int -> CaseFirst -> ShowS
    [CaseFirst] -> ShowS
    CaseFirst -> String
    (Int -> CaseFirst -> ShowS)
    -> (CaseFirst -> String)
    -> ([CaseFirst] -> ShowS)
    -> Show CaseFirst
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> CaseFirst -> ShowS
    showsPrec :: Int -> CaseFirst -> ShowS
    $cshow :: CaseFirst -> String
    show :: CaseFirst -> String
    $cshowList :: [CaseFirst] -> ShowS
    showList :: [CaseFirst] -> ShowS
    Show, Typeable)

    instance NFData CaseFirst where
        rnf :: CaseFirst -> ()
    rnf !CaseFirst
    _ = ()

    -- | The strength attribute. The usual strength for most locales (except
    -- Japanese) is tertiary. Quaternary strength is useful when combined with
    -- shifted setting for alternate handling attribute and for JIS x 4061
    -- collation, when it is used to distinguish between Katakana and Hiragana
    -- (this is achieved by setting 'HiraganaQuaternaryMode' mode to
    -- 'True'). Otherwise, quaternary level is affected only by the number of
    -- non ignorable codepoints in the string. Identical strength is rarely
    -- useful, as it amounts to codepoints of the 'NFD' form of the string.
    data Strength = Primary
                  | Secondary
                  | Tertiary
                  | Quaternary
                  | Identical
                    deriving (Strength -> Strength -> Bool
    (Strength -> Strength -> Bool)
    -> (Strength -> Strength -> Bool) -> Eq Strength
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Strength -> Strength -> Bool
    == :: Strength -> Strength -> Bool
    $c/= :: Strength -> Strength -> Bool
    /= :: Strength -> Strength -> Bool
    Eq, Strength
    Strength -> Strength -> Bounded Strength
    forall a. a -> a -> Bounded a
    $cminBound :: Strength
    minBound :: Strength
    $cmaxBound :: Strength
    maxBound :: Strength
    Bounded, Int -> Strength
    Strength -> Int
    Strength -> [Strength]
    Strength -> Strength
    Strength -> Strength -> [Strength]
    Strength -> Strength -> Strength -> [Strength]
    (Strength -> Strength)
    -> (Strength -> Strength)
    -> (Int -> Strength)
    -> (Strength -> Int)
    -> (Strength -> [Strength])
    -> (Strength -> Strength -> [Strength])
    -> (Strength -> Strength -> [Strength])
    -> (Strength -> Strength -> Strength -> [Strength])
    -> Enum Strength
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: Strength -> Strength
    succ :: Strength -> Strength
    $cpred :: Strength -> Strength
    pred :: Strength -> Strength
    $ctoEnum :: Int -> Strength
    toEnum :: Int -> Strength
    $cfromEnum :: Strength -> Int
    fromEnum :: Strength -> Int
    $cenumFrom :: Strength -> [Strength]
    enumFrom :: Strength -> [Strength]
    $cenumFromThen :: Strength -> Strength -> [Strength]
    enumFromThen :: Strength -> Strength -> [Strength]
    $cenumFromTo :: Strength -> Strength -> [Strength]
    enumFromTo :: Strength -> Strength -> [Strength]
    $cenumFromThenTo :: Strength -> Strength -> Strength -> [Strength]
    enumFromThenTo :: Strength -> Strength -> Strength -> [Strength]
    Enum, Int -> Strength -> ShowS
    [Strength] -> ShowS
    Strength -> String
    (Int -> Strength -> ShowS)
    -> (Strength -> String) -> ([Strength] -> ShowS) -> Show Strength
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Strength -> ShowS
    showsPrec :: Int -> Strength -> ShowS
    $cshow :: Strength -> String
    show :: Strength -> String
    $cshowList :: [Strength] -> ShowS
    showList :: [Strength] -> ShowS
    Show, Typeable)

    instance NFData Strength where
        rnf :: Strength -> ()
    rnf !Strength
    _ = ()

    data Attribute = French Bool
                   -- ^ Direction of secondary weights, used in French.  'True',
                   -- results in secondary weights being considered backwards,
                   -- while 'False' treats secondary weights in the order in
                   -- which they appear.
                   | AlternateHandling AlternateHandling
                     -- ^ For handling variable elements.  'NonIgnorable' is
                     -- default.
                   | CaseFirst (Maybe CaseFirst)
                   -- ^ Control the ordering of upper and lower case letters.
                   -- 'Nothing' (the default) orders upper and lower case
                   -- letters in accordance to their tertiary weights.
                   | CaseLevel Bool
                     -- ^ Controls whether an extra case level (positioned
                     -- before the third level) is generated or not.  When
                     -- 'False' (default), case level is not generated; when
                     -- 'True', the case level is generated. Contents of the
                     -- case level are affected by the value of the 'CaseFirst'
                     -- attribute. A simple way to ignore accent differences in
                     -- a string is to set the strength to 'Primary' and enable
                     -- case level.
                   | NormalizationMode Bool
                   -- ^ Controls whether the normalization check and necessary
                   -- normalizations are performed. When 'False' (default) no
                   -- normalization check is performed. The correctness of the
                   -- result is guaranteed only if the input data is in
                   -- so-called 'FCD' form (see users manual for more info).
                   -- When 'True', an incremental check is performed to see
                   -- whether the input data is in 'FCD' form. If the data is
                   -- not in 'FCD' form, incremental 'NFD' normalization is
                   -- performed.
                   | Strength Strength
                   | HiraganaQuaternaryMode Bool
                     -- ^ When turned on, this attribute positions Hiragana
                     -- before all non-ignorables on quaternary level. This is a
                     -- sneaky way to produce JIS sort order.
                   | Numeric Bool
                     -- ^ When enabled, this attribute generates a collation key
                     -- for the numeric value of substrings of digits.  This is
                     -- a way to get '100' to sort /after/ '2'.
                     deriving (Attribute -> Attribute -> Bool
    (Attribute -> Attribute -> Bool)
    -> (Attribute -> Attribute -> Bool) -> Eq Attribute
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Attribute -> Attribute -> Bool
    == :: Attribute -> Attribute -> Bool
    $c/= :: Attribute -> Attribute -> Bool
    /= :: Attribute -> Attribute -> Bool
    Eq, Int -> Attribute -> ShowS
    [Attribute] -> ShowS
    Attribute -> String
    (Int -> Attribute -> ShowS)
    -> (Attribute -> String)
    -> ([Attribute] -> ShowS)
    -> Show Attribute
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Attribute -> ShowS
    showsPrec :: Int -> Attribute -> ShowS
    $cshow :: Attribute -> String
    show :: Attribute -> String
    $cshowList :: [Attribute] -> ShowS
    showList :: [Attribute] -> ShowS
    Show, Typeable)

    instance NFData Attribute where
        rnf :: Attribute -> ()
    rnf (French !Bool
    _)                 = ()
        rnf (AlternateHandling !AlternateHandling
    _)      = ()
        rnf (CaseFirst Maybe CaseFirst
    c)               = Maybe CaseFirst -> ()
    forall a. NFData a => a -> ()
    rnf Maybe CaseFirst
    c
        rnf (CaseLevel !Bool
    _)              = ()
        rnf (NormalizationMode !Bool
    _)      = ()
        rnf (Strength !Strength
    _)               = ()
        rnf (HiraganaQuaternaryMode !Bool
    _) = ()
        rnf (Numeric !Bool
    _)                = ()

    type UColAttribute = CInt
    type UColAttributeValue = CInt
    type UCollationStrength = UColAttributeValue

    toUAttribute :: Attribute -> (UColAttribute, UColAttributeValue)
    toUAttribute :: Attribute -> (UCollationResult, UCollationResult)
    toUAttribute (French Bool
    v)
        = ((UCollationResult
    0), Bool -> UCollationResult
    toOO Bool
    v)
    {-# LINE 169 "Data/Text/ICU/Collate.hsc" #-}
    toUAttribute (AlternateHandling v)
        = ((1), toAH v)
    {-# LINE 171 "Data/Text/ICU/Collate.hsc" #-}
    toUAttribute (CaseFirst v)
        = ((2), toCF v)
    {-# LINE 173 "Data/Text/ICU/Collate.hsc" #-}
    toUAttribute (CaseLevel v)
        = ((3), toOO v)
    {-# LINE 175 "Data/Text/ICU/Collate.hsc" #-}
    toUAttribute (NormalizationMode v)
        = ((4), toOO v)
    {-# LINE 177 "Data/Text/ICU/Collate.hsc" #-}
    toUAttribute (Strength v)
        = ((5), toS v)
    {-# LINE 179 "Data/Text/ICU/Collate.hsc" #-}
    toUAttribute (HiraganaQuaternaryMode v)
        = ((6), toOO v)
    {-# LINE 181 "Data/Text/ICU/Collate.hsc" #-}
    toUAttribute (Numeric v)
        = ((7), toOO v)
    {-# LINE 183 "Data/Text/ICU/Collate.hsc" #-}

    toOO :: Bool -> UColAttributeValue
    toOO :: Bool -> UCollationResult
    toOO Bool
    False = UCollationResult
    16
    {-# LINE 186 "Data/Text/ICU/Collate.hsc" #-}
    toOO True  = 17
    {-# LINE 187 "Data/Text/ICU/Collate.hsc" #-}

    toDefaultOO :: (Maybe Bool) -> UColAttributeValue
    toDefaultOO :: Maybe Bool -> UCollationResult
    toDefaultOO (Just Bool
    False) = UCollationResult
    16
    {-# LINE 190 "Data/Text/ICU/Collate.hsc" #-}
    toDefaultOO (Just True)  = 17
    {-# LINE 191 "Data/Text/ICU/Collate.hsc" #-}
    toDefaultOO Nothing  = -1
    {-# LINE 192 "Data/Text/ICU/Collate.hsc" #-}

    toAH :: AlternateHandling -> UColAttributeValue
    toAH :: AlternateHandling -> UCollationResult
    toAH AlternateHandling
    NonIgnorable = UCollationResult
    21
    {-# LINE 195 "Data/Text/ICU/Collate.hsc" #-}
    toAH Shifted      = 20
    {-# LINE 196 "Data/Text/ICU/Collate.hsc" #-}

    toCF :: Maybe CaseFirst -> UColAttributeValue
    toCF :: Maybe CaseFirst -> UCollationResult
    toCF Maybe CaseFirst
    Nothing           = UCollationResult
    16
    {-# LINE 199 "Data/Text/ICU/Collate.hsc" #-}
    toCF (Just UpperFirst) = 25
    {-# LINE 200 "Data/Text/ICU/Collate.hsc" #-}
    toCF (Just LowerFirst) = 24
    {-# LINE 201 "Data/Text/ICU/Collate.hsc" #-}

    toS :: Strength -> UColAttributeValue
    toS :: Strength -> UCollationResult
    toS Strength
    Primary    = UCollationResult
    0
    {-# LINE 204 "Data/Text/ICU/Collate.hsc" #-}
    toS Secondary  = 1
    {-# LINE 205 "Data/Text/ICU/Collate.hsc" #-}
    toS Tertiary   = 2
    {-# LINE 206 "Data/Text/ICU/Collate.hsc" #-}
    toS Quaternary = 3
    {-# LINE 207 "Data/Text/ICU/Collate.hsc" #-}
    toS Identical  = 15
    {-# LINE 208 "Data/Text/ICU/Collate.hsc" #-}

    toDefaultS :: Maybe Strength -> UColAttributeValue
    toDefaultS :: Maybe Strength -> UCollationResult
    toDefaultS (Just Strength
    s)    = Strength -> UCollationResult
    toS Strength
    s
    toDefaultS Maybe Strength
    Nothing  = UCollationResult
    2
    {-# LINE 212 "Data/Text/ICU/Collate.hsc" #-}

    fromOO :: UColAttributeValue -> Bool
    fromOO :: UCollationResult -> Bool
    fromOO (UCollationResult
    16) = Bool
    False
    {-# LINE 215 "Data/Text/ICU/Collate.hsc" #-}
    fromOO (17)  = True
    {-# LINE 216 "Data/Text/ICU/Collate.hsc" #-}
    fromOO bad = valueError "fromOO" bad

    fromAH :: UColAttributeValue -> AlternateHandling
    fromAH :: UCollationResult -> AlternateHandling
    fromAH (UCollationResult
    21) = AlternateHandling
    NonIgnorable
    {-# LINE 220 "Data/Text/ICU/Collate.hsc" #-}
    fromAH (20)       = Shifted
    {-# LINE 221 "Data/Text/ICU/Collate.hsc" #-}
    fromAH bad = valueError "fromAH" bad

    fromCF :: UColAttributeValue -> Maybe CaseFirst
    fromCF :: UCollationResult -> Maybe CaseFirst
    fromCF (UCollationResult
    16)         = Maybe CaseFirst
    forall a. Maybe a
    Nothing
    {-# LINE 225 "Data/Text/ICU/Collate.hsc" #-}
    fromCF (25) = Just UpperFirst
    {-# LINE 226 "Data/Text/ICU/Collate.hsc" #-}
    fromCF (24) = Just LowerFirst
    {-# LINE 227 "Data/Text/ICU/Collate.hsc" #-}
    fromCF bad = valueError "fromCF" bad

    fromS :: UColAttributeValue -> Strength
    fromS :: UCollationResult -> Strength
    fromS (UCollationResult
    0)    = Strength
    Primary
    {-# LINE 231 "Data/Text/ICU/Collate.hsc" #-}
    fromS (1)  = Secondary
    {-# LINE 232 "Data/Text/ICU/Collate.hsc" #-}
    fromS (2)   = Tertiary
    {-# LINE 233 "Data/Text/ICU/Collate.hsc" #-}
    fromS (3) = Quaternary
    {-# LINE 234 "Data/Text/ICU/Collate.hsc" #-}
    fromS (15)  = Identical
    {-# LINE 235 "Data/Text/ICU/Collate.hsc" #-}
    fromS bad = valueError "fromS" bad

    fromUAttribute :: UColAttribute -> UColAttributeValue -> Attribute
    fromUAttribute :: UCollationResult -> UCollationResult -> Attribute
    fromUAttribute UCollationResult
    key UCollationResult
    val =
      case UCollationResult
    key of
        (UCollationResult
    0)         -> Bool -> Attribute
    French (UCollationResult -> Bool
    fromOO UCollationResult
    val)
    {-# LINE 241 "Data/Text/ICU/Collate.hsc" #-}
        (1)       -> AlternateHandling (fromAH val)
    {-# LINE 242 "Data/Text/ICU/Collate.hsc" #-}
        (2)               -> CaseFirst (fromCF val)
    {-# LINE 243 "Data/Text/ICU/Collate.hsc" #-}
        (3)               -> CaseLevel (fromOO val)
    {-# LINE 244 "Data/Text/ICU/Collate.hsc" #-}
        (4)       -> NormalizationMode (fromOO val)
    {-# LINE 245 "Data/Text/ICU/Collate.hsc" #-}
        (5)                 -> Strength (fromS val)
    {-# LINE 246 "Data/Text/ICU/Collate.hsc" #-}
        (6) -> HiraganaQuaternaryMode (fromOO val)
    {-# LINE 247 "Data/Text/ICU/Collate.hsc" #-}
        (7)        -> Numeric (fromOO val)
    {-# LINE 248 "Data/Text/ICU/Collate.hsc" #-}
        _ -> valueError "fromUAttribute" key

    valueError :: Show a => String -> a -> z
    valueError :: forall a z. Show a => String -> a -> z
    valueError String
    func a
    bad = String -> z
    forall a. HasCallStack => String -> a
    error (String
    "Data.Text.ICU.Collate." String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    func String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
                                 String
    ": invalid value " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ a -> String
    forall a. Show a => a -> String
    show a
    bad)

    type UCollationResult = CInt

    -- | Open a 'Collator' for comparing strings.
    open :: LocaleName
         -- ^ The locale containing the required collation rules.
         -> IO MCollator
    open :: LocaleName -> IO MCollator
    open LocaleName
    loc = IO (Ptr UCollator) -> IO MCollator
    wrap (IO (Ptr UCollator) -> IO MCollator)
    -> IO (Ptr UCollator) -> IO MCollator
    forall a b. (a -> b) -> a -> b
    $ LocaleName -> (CString -> IO (Ptr UCollator)) -> IO (Ptr UCollator)
    forall a. LocaleName -> (CString -> IO a) -> IO a
    withLocaleName LocaleName
    loc ((Ptr UCollationResult -> IO (Ptr UCollator)) -> IO (Ptr UCollator)
    forall a. (Ptr UCollationResult -> IO a) -> IO a
    handleError ((Ptr UCollationResult -> IO (Ptr UCollator))
     -> IO (Ptr UCollator))
    -> (CString -> Ptr UCollationResult -> IO (Ptr UCollator))
    -> CString
    -> IO (Ptr UCollator)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CString -> Ptr UCollationResult -> IO (Ptr UCollator)
    ucol_open)

    -- | Produce a 'Collator' instance according to the rules supplied.
    openRules :: Text
              -- ^ A string describing the collation rules.
              -> Maybe Bool
              -- ^ The normalization mode: One of 'Just False' (expect the text to not need normalization)
              -- 'Just True' (normalize), or 'Nothing' (set the mode according to the rules)
              -> Maybe Strength
              -- ^ The default collation strength; one of 'Just Primary', 'Just Secondary', 'Just Tertiary', 'Just Identical', 'Nothing' (default strength) - can be also set in the rules.
              -> IO MCollator
    openRules :: Text -> Maybe Bool -> Maybe Strength -> IO MCollator
    openRules Text
    r Maybe Bool
    n Maybe Strength
    s = IO (Ptr UCollator) -> IO MCollator
    wrap (IO (Ptr UCollator) -> IO MCollator)
    -> IO (Ptr UCollator) -> IO MCollator
    forall a b. (a -> b) -> a -> b
    $ Text
    -> (Ptr UChar -> I16 -> IO (Ptr UCollator)) -> IO (Ptr UCollator)
    forall a. Text -> (Ptr UChar -> I16 -> IO a) -> IO a
    useAsUCharPtr Text
    r ((Ptr UChar -> I16 -> IO (Ptr UCollator)) -> IO (Ptr UCollator))
    -> (Ptr UChar -> I16 -> IO (Ptr UCollator)) -> IO (Ptr UCollator)
    forall a b. (a -> b) -> a -> b
    $ \Ptr UChar
    rPtr I16
    rLen -> do
      let len :: Int32
    len = I16 -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral I16
    rLen
      (ICUError -> Bool)
    -> (Ptr UParseError -> Ptr UCollationResult -> IO (Ptr UCollator))
    -> IO (Ptr UCollator)
    forall a.
    (ICUError -> Bool)
    -> (Ptr UParseError -> Ptr UCollationResult -> IO a) -> IO a
    handleParseError (ICUError -> ICUError -> Bool
    forall a. Eq a => a -> a -> Bool
    == ICUError
    u_INVALID_FORMAT_ERROR) ((Ptr UParseError -> Ptr UCollationResult -> IO (Ptr UCollator))
     -> IO (Ptr UCollator))
    -> (Ptr UParseError -> Ptr UCollationResult -> IO (Ptr UCollator))
    -> IO (Ptr UCollator)
    forall a b. (a -> b) -> a -> b
    $ Ptr UChar
    -> Int32
    -> UCollationResult
    -> UCollationResult
    -> Ptr UParseError
    -> Ptr UCollationResult
    -> IO (Ptr UCollator)
    ucol_openRules Ptr UChar
    rPtr Int32
    len (Maybe Bool -> UCollationResult
    toDefaultOO Maybe Bool
    n) (Maybe Strength -> UCollationResult
    toDefaultS Maybe Strength
    s)

    -- | Get the rules of an 'MCollator' attribute.
    getRules :: MCollator -> IO Text
    getRules :: MCollator -> IO Text
    getRules MCollator
    c =
      MCollator -> (Ptr UCollator -> IO Text) -> IO Text
    forall a. MCollator -> (Ptr UCollator -> IO a) -> IO a
    withCollator MCollator
    c ((Ptr UCollator -> IO Text) -> IO Text)
    -> (Ptr UCollator -> IO Text) -> IO Text
    forall a b. (a -> b) -> a -> b
    $ \Ptr UCollator
    cPtr ->
        (Ptr Int32 -> IO Text) -> IO Text
    forall a b. Storable a => (Ptr a -> IO b) -> IO b
    alloca ((Ptr Int32 -> IO Text) -> IO Text)
    -> (Ptr Int32 -> IO Text) -> IO Text
    forall a b. (a -> b) -> a -> b
    $ \Ptr Int32
    lenPtr -> do
          textPtr <- Ptr UCollator -> Ptr Int32 -> IO (Ptr UChar)
    ucol_getRules Ptr UCollator
    cPtr Ptr Int32
    lenPtr
          (fromUCharPtr textPtr . fromIntegral) =<< peek lenPtr

    -- | Set the value of an 'MCollator' attribute.
    setAttribute :: MCollator -> Attribute -> IO ()
    setAttribute :: MCollator -> Attribute -> IO ()
    setAttribute MCollator
    c Attribute
    a =
      MCollator -> (Ptr UCollator -> IO ()) -> IO ()
    forall a. MCollator -> (Ptr UCollator -> IO a) -> IO a
    withCollator MCollator
    c ((Ptr UCollator -> IO ()) -> IO ())
    -> (Ptr UCollator -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Ptr UCollator
    cptr ->
        (Ptr UCollationResult -> IO ()) -> IO ()
    forall a. (Ptr UCollationResult -> IO a) -> IO a
    handleError ((Ptr UCollationResult -> IO ()) -> IO ())
    -> (Ptr UCollationResult -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ (UCollationResult
     -> UCollationResult -> Ptr UCollationResult -> IO ())
    -> (UCollationResult, UCollationResult)
    -> Ptr UCollationResult
    -> IO ()
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry (Ptr UCollator
    -> UCollationResult
    -> UCollationResult
    -> Ptr UCollationResult
    -> IO ()
    ucol_setAttribute Ptr UCollator
    cptr) (Attribute -> (UCollationResult, UCollationResult)
    toUAttribute Attribute
    a)

    -- | Get the value of an 'MCollator' attribute.
    --
    -- It is safe to provide a dummy argument to an 'Attribute' constructor when
    -- using this function, so the following will work:
    --
    -- > getAttribute mcol (NormalizationMode undefined)
    getAttribute :: MCollator -> Attribute -> IO Attribute
    getAttribute :: MCollator -> Attribute -> IO Attribute
    getAttribute MCollator
    c Attribute
    a = do
      let name :: UCollationResult
    name = (UCollationResult, UCollationResult) -> UCollationResult
    forall a b. (a, b) -> a
    fst (Attribute -> (UCollationResult, UCollationResult)
    toUAttribute Attribute
    a)
      val <- MCollator
    -> (Ptr UCollator -> IO UCollationResult) -> IO UCollationResult
    forall a. MCollator -> (Ptr UCollator -> IO a) -> IO a
    withCollator MCollator
    c ((Ptr UCollator -> IO UCollationResult) -> IO UCollationResult)
    -> (Ptr UCollator -> IO UCollationResult) -> IO UCollationResult
    forall a b. (a -> b) -> a -> b
    $ \Ptr UCollator
    cptr -> (Ptr UCollationResult -> IO UCollationResult)
    -> IO UCollationResult
    forall a. (Ptr UCollationResult -> IO a) -> IO a
    handleError ((Ptr UCollationResult -> IO UCollationResult)
     -> IO UCollationResult)
    -> (Ptr UCollationResult -> IO UCollationResult)
    -> IO UCollationResult
    forall a b. (a -> b) -> a -> b
    $ Ptr UCollator
    -> UCollationResult -> Ptr UCollationResult -> IO UCollationResult
    ucol_getAttribute Ptr UCollator
    cptr UCollationResult
    name
      return $! fromUAttribute name val

    -- | Compare two strings.
    collate :: MCollator -> Text -> Text -> IO Ordering
    collate :: MCollator -> Text -> Text -> IO Ordering
    collate MCollator
    c Text
    a Text
    b =
      MCollator -> (Ptr UCollator -> IO Ordering) -> IO Ordering
    forall a. MCollator -> (Ptr UCollator -> IO a) -> IO a
    withCollator MCollator
    c ((Ptr UCollator -> IO Ordering) -> IO Ordering)
    -> (Ptr UCollator -> IO Ordering) -> IO Ordering
    forall a b. (a -> b) -> a -> b
    $ \Ptr UCollator
    cptr ->
        Text -> (Ptr Word8 -> I8 -> IO Ordering) -> IO Ordering
    forall a. Text -> (Ptr Word8 -> I8 -> IO a) -> IO a
    useAsPtr Text
    a ((Ptr Word8 -> I8 -> IO Ordering) -> IO Ordering)
    -> (Ptr Word8 -> I8 -> IO Ordering) -> IO Ordering
    forall a b. (a -> b) -> a -> b
    $ \Ptr Word8
    aptr I8
    alen ->
          Text -> (Ptr Word8 -> I8 -> IO Ordering) -> IO Ordering
    forall a. Text -> (Ptr Word8 -> I8 -> IO a) -> IO a
    useAsPtr Text
    b ((Ptr Word8 -> I8 -> IO Ordering) -> IO Ordering)
    -> (Ptr Word8 -> I8 -> IO Ordering) -> IO Ordering
    forall a b. (a -> b) -> a -> b
    $ \Ptr Word8
    bptr I8
    blen ->
            (UCollationResult -> Ordering)
    -> IO UCollationResult -> IO Ordering
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap UCollationResult -> Ordering
    forall a. Integral a => a -> Ordering
    asOrdering (IO UCollationResult -> IO Ordering)
    -> ((Ptr UCollationResult -> IO UCollationResult)
        -> IO UCollationResult)
    -> (Ptr UCollationResult -> IO UCollationResult)
    -> IO Ordering
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Ptr UCollationResult -> IO UCollationResult)
    -> IO UCollationResult
    forall a. (Ptr UCollationResult -> IO a) -> IO a
    handleError ((Ptr UCollationResult -> IO UCollationResult) -> IO Ordering)
    -> (Ptr UCollationResult -> IO UCollationResult) -> IO Ordering
    forall a b. (a -> b) -> a -> b
    $

    {-# LINE 309 "Data/Text/ICU/Collate.hsc" #-}
            Ptr UCollator
    -> Ptr Word8
    -> Int32
    -> Ptr Word8
    -> Int32
    -> Ptr UCollationResult
    -> IO UCollationResult
    ucol_strcollUTF8

    {-# LINE 313 "Data/Text/ICU/Collate.hsc" #-}
            Ptr UCollator
    cptr Ptr Word8
    aptr (I8 -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral I8
    alen) Ptr Word8
    bptr (I8 -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral I8
    blen)

    -- | Compare two 'CharIterator's.
    --
    -- If either iterator was constructed from a 'ByteString', it does not need
    -- to be copied or converted internally, so this function can be quite
    -- cheap.
    collateIter :: MCollator -> CharIterator -> CharIterator -> IO Ordering
    collateIter :: MCollator -> CharIterator -> CharIterator -> IO Ordering
    collateIter MCollator
    c CharIterator
    a CharIterator
    b =
      (UCollationResult -> Ordering)
    -> IO UCollationResult -> IO Ordering
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap UCollationResult -> Ordering
    forall a. Integral a => a -> Ordering
    asOrdering (IO UCollationResult -> IO Ordering)
    -> ((Ptr UCollator -> IO UCollationResult) -> IO UCollationResult)
    -> (Ptr UCollator -> IO UCollationResult)
    -> IO Ordering
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . MCollator
    -> (Ptr UCollator -> IO UCollationResult) -> IO UCollationResult
    forall a. MCollator -> (Ptr UCollator -> IO a) -> IO a
    withCollator MCollator
    c ((Ptr UCollator -> IO UCollationResult) -> IO Ordering)
    -> (Ptr UCollator -> IO UCollationResult) -> IO Ordering
    forall a b. (a -> b) -> a -> b
    $ \Ptr UCollator
    cptr ->
        CharIterator
    -> (Ptr UCharIterator -> IO UCollationResult)
    -> IO UCollationResult
    forall a. CharIterator -> (Ptr UCharIterator -> IO a) -> IO a
    withCharIterator CharIterator
    a ((Ptr UCharIterator -> IO UCollationResult) -> IO UCollationResult)
    -> (Ptr UCharIterator -> IO UCollationResult)
    -> IO UCollationResult
    forall a b. (a -> b) -> a -> b
    $ \Ptr UCharIterator
    ai ->
          CharIterator
    -> (Ptr UCharIterator -> IO UCollationResult)
    -> IO UCollationResult
    forall a. CharIterator -> (Ptr UCharIterator -> IO a) -> IO a
    withCharIterator CharIterator
    b ((Ptr UCharIterator -> IO UCollationResult) -> IO UCollationResult)
    -> (Ptr UCharIterator -> IO UCollationResult)
    -> IO UCollationResult
    forall a b. (a -> b) -> a -> b
    $ (Ptr UCollationResult -> IO UCollationResult)
    -> IO UCollationResult
    forall a. (Ptr UCollationResult -> IO a) -> IO a
    handleError ((Ptr UCollationResult -> IO UCollationResult)
     -> IO UCollationResult)
    -> (Ptr UCharIterator
        -> Ptr UCollationResult -> IO UCollationResult)
    -> Ptr UCharIterator
    -> IO UCollationResult
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Ptr UCollator
    -> Ptr UCharIterator
    -> Ptr UCharIterator
    -> Ptr UCollationResult
    -> IO UCollationResult
    ucol_strcollIter Ptr UCollator
    cptr Ptr UCharIterator
    ai

    -- | Create a key for sorting the 'Text' using the given 'Collator'.
    -- The result of comparing two 'ByteString's that have been
    -- transformed with 'sortKey' will be the same as the result of
    -- 'collate' on the two untransformed 'Text's.
    sortKey :: MCollator -> Text -> IO ByteString
    sortKey :: MCollator -> Text -> IO ByteString
    sortKey MCollator
    c Text
    t
        | Text -> Bool
    T.null Text
    t = ByteString -> IO ByteString
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ByteString
    empty
        | Bool
    otherwise = do
      MCollator -> (Ptr UCollator -> IO ByteString) -> IO ByteString
    forall a. MCollator -> (Ptr UCollator -> IO a) -> IO a
    withCollator MCollator
    c ((Ptr UCollator -> IO ByteString) -> IO ByteString)
    -> (Ptr UCollator -> IO ByteString) -> IO ByteString
    forall a b. (a -> b) -> a -> b
    $ \Ptr UCollator
    cptr ->
        Text -> (Ptr UChar -> I16 -> IO ByteString) -> IO ByteString
    forall a. Text -> (Ptr UChar -> I16 -> IO a) -> IO a
    useAsUCharPtr Text
    t ((Ptr UChar -> I16 -> IO ByteString) -> IO ByteString)
    -> (Ptr UChar -> I16 -> IO ByteString) -> IO ByteString
    forall a b. (a -> b) -> a -> b
    $ \Ptr UChar
    tptr I16
    tlen -> do
          let len :: Int32
    len = I16 -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral I16
    tlen
              loop :: Int32 -> IO ByteString
    loop Int32
    n = do
                fp <- Int -> IO (ForeignPtr Word8)
    forall a. Int -> IO (ForeignPtr a)
    mallocByteString (Int32 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int32
    n)
                i <- withForeignPtr fp $ \Ptr Word8
    p -> Ptr UCollator
    -> Ptr UChar -> Int32 -> Ptr Word8 -> Int32 -> IO Int32
    ucol_getSortKey Ptr UCollator
    cptr Ptr UChar
    tptr Int32
    len Ptr Word8
    p Int32
    n
                let j = Int32 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int32
    i
                case undefined of
                  ZonkAny 1
    _ | Int32
    i Int32 -> Int32 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int32
    0         -> String -> IO ByteString
    forall a. HasCallStack => String -> a
    error String
    "Data.Text.ICU.Collate.sortKey: internal error"
                    | Int32
    i Int32 -> Int32 -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int32
    n          -> Int32 -> IO ByteString
    loop Int32
    i
                    | Int32
    i Int32 -> Int32 -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int32
    n Int32 -> Int32 -> Int32
    forall a. Integral a => a -> a -> a
    `div` Int32
    2 -> Int -> (Ptr Word8 -> IO ()) -> IO ByteString
    create Int
    j ((Ptr Word8 -> IO ()) -> IO ByteString)
    -> (Ptr Word8 -> IO ()) -> IO ByteString
    forall a b. (a -> b) -> a -> b
    $ \Ptr Word8
    p -> ForeignPtr Word8 -> (Ptr Word8 -> IO ()) -> IO ()
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr ForeignPtr Word8
    fp ((Ptr Word8 -> IO ()) -> IO ()) -> (Ptr Word8 -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Ptr Word8
    op ->
                                        Ptr Word8 -> Ptr Word8 -> Int -> IO ()
    memcpy Ptr Word8
    p Ptr Word8
    op (Int32 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int32
    i)
                    | Bool
    otherwise      -> ByteString -> IO ByteString
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (ByteString -> IO ByteString) -> ByteString -> IO ByteString
    forall a b. (a -> b) -> a -> b
    $! ForeignPtr Word8 -> Int -> Int -> ByteString
    PS ForeignPtr Word8
    fp Int
    0 Int
    j
          Int32 -> IO ByteString
    loop (Int32 -> Int32 -> Int32
    forall a. Ord a => a -> a -> a
    min (Int32
    len Int32 -> Int32 -> Int32
    forall a. Num a => a -> a -> a
    * Int32
    4) Int32
    8)

    -- | Make a safe copy of a mutable 'MCollator' for use in pure code.
    -- Subsequent changes to the 'MCollator' will not affect the state of
    -- the returned 'Collator'.
    freeze :: MCollator -> IO Collator
    freeze :: MCollator -> IO Collator
    freeze = (MCollator -> Collator) -> IO MCollator -> IO Collator
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap MCollator -> Collator
    C (IO MCollator -> IO Collator)
    -> (MCollator -> IO MCollator) -> MCollator -> IO Collator
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . MCollator -> IO MCollator
    clone

    -- | Make a copy of a mutable 'MCollator'.
    -- Subsequent changes to the input 'MCollator' will not affect the state of
    -- the returned 'MCollator'.
    clone :: MCollator -> IO MCollator
    clone :: MCollator -> IO MCollator
    clone MCollator
    c =
      IO (Ptr UCollator) -> IO MCollator
    wrap (IO (Ptr UCollator) -> IO MCollator)
    -> IO (Ptr UCollator) -> IO MCollator
    forall a b. (a -> b) -> a -> b
    $ MCollator
    -> (Ptr UCollator -> IO (Ptr UCollator)) -> IO (Ptr UCollator)
    forall a. MCollator -> (Ptr UCollator -> IO a) -> IO a
    withCollator MCollator
    c ((Ptr UCollator -> IO (Ptr UCollator)) -> IO (Ptr UCollator))
    -> (Ptr UCollator -> IO (Ptr UCollator)) -> IO (Ptr UCollator)
    forall a b. (a -> b) -> a -> b
    $ \Ptr UCollator
    cptr ->
        Int32 -> (Ptr Int32 -> IO (Ptr UCollator)) -> IO (Ptr UCollator)
    forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
    with (Int32
    1)
    {-# LINE 362 "Data/Text/ICU/Collate.hsc" #-}
          (handleError . ucol_safeClone cptr nullPtr)

    foreign import ccall unsafe "hs_text_icu.h __hs_ucol_open" ucol_open
        :: CString -> Ptr UErrorCode -> IO (Ptr UCollator)

    foreign import ccall unsafe "hs_text_icu.h __hs_ucol_openRules" ucol_openRules
        :: Ptr UChar -> Int32 -> UColAttributeValue -> UCollationStrength -> Ptr UParseError -> Ptr UErrorCode -> IO (Ptr UCollator)

    foreign import ccall unsafe "hs_text_icu.h __hs_ucol_getAttribute" ucol_getAttribute
        :: Ptr UCollator -> UColAttribute -> Ptr UErrorCode -> IO UColAttributeValue

    foreign import ccall unsafe "hs_text_icu.h __hs_ucol_getRules" ucol_getRules
        :: Ptr UCollator -> Ptr Int32 -> IO (Ptr UChar)

    foreign import ccall unsafe "hs_text_icu.h __hs_ucol_setAttribute" ucol_setAttribute
        :: Ptr UCollator -> UColAttribute -> UColAttributeValue -> Ptr UErrorCode -> IO ()

    {-# LINE 380 "Data/Text/ICU/Collate.hsc" #-}
    foreign import ccall unsafe "hs_text_icu.h __hs_ucol_strcollUTF8" ucol_strcollUTF8
        :: Ptr UCollator -> Ptr Word8 -> Int32 -> Ptr Word8 -> Int32
        -> Ptr UErrorCode -> IO UCollationResult

    {-# LINE 388 "Data/Text/ICU/Collate.hsc" #-}

    foreign import ccall unsafe "hs_text_icu.h __hs_ucol_getSortKey" ucol_getSortKey
        :: Ptr UCollator -> Ptr UChar -> Int32 -> Ptr Word8 -> Int32
        -> IO Int32

    foreign import ccall unsafe "hs_text_icu.h __hs_ucol_strcollIter" ucol_strcollIter
        :: Ptr UCollator -> Ptr UCharIterator -> Ptr UCharIterator -> Ptr UErrorCode
        -> IO UCollationResult

    foreign import ccall unsafe "hs_text_icu.h __hs_ucol_safeClone" ucol_safeClone
            :: Ptr UCollator -> Ptr a -> Ptr Int32 -> Ptr UErrorCode
            -> IO (Ptr UCollator)