    {-# LANGUAGE MagicHash, CPP #-}

    -- | Char8 library to be used with Data.ByteString.Char8.
    -- All function assumes that only 8bit part of 'Char' is used
    -- and it is encoded in Latin-1 (ISO-8859-1).
    -- All utility functions are supposed to work as if
    -- those of 'Data.Char'. Exceptions are described in
    -- the function documentations.
    --
    -- Base library 4.7 (GHC 7.8) or earlier is based on Unicode 6.
    -- Base library 4.8 (GHC 7.10) or later is based on Unicode 7.
    -- 'isLower', 'isSymbol' and 'isPunctuation' behave differently.

    module Data.Char8 (
      -- * Character classification
        isControl, isSpace, isLower, isUpper
      , isAlpha, isAlphaNum, isPrint, isDigit, isOctDigit, isHexDigit
      , isLetter, isMark, isNumber, isPunctuation, isSymbol, isSeparator
      -- * Subranges
      , isAscii, isLatin1, isAsciiUpper, isAsciiLower
      -- * Case conversion
      , toUpper, toLower, toTitle
      ) where

    import GHC.Base
    ----------------------------------------------------------------

    isControl :: Char -> Bool
    isControl :: Char -> Bool
    isControl Char
    c = Char
    _nul Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    c Bool -> Bool -> Bool
    && Char
    c Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    '\x1f'
               Bool -> Bool -> Bool
    || Char
    _del Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    c Bool -> Bool -> Bool
    && Char
    c Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    '\x9f'

    isSpace :: Char -> Bool
    isSpace :: Char -> Bool
    isSpace Char
    c = Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    _space
             Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    _tab
             Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    _lf
             Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    _cr
             Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    _np
             Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    _vt
             Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    _nbsp

    -- | This function returns 'True' for 170 and 186 in Unicode 6.
    --   But it returns 'False' in Unicode 7.
    isLower :: Char -> Bool
    isLower :: Char -> Bool
    isLower Char
    c = Char -> Bool
    isLower' Char
    c
             Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    _mu
    #if !MIN_VERSION_base(4,8,0)
             || c == _ordfeminine
             || c == _ordmasculine
    #endif

    isLowerCommon :: Char -> Bool
    isLowerCommon :: Char -> Bool
    isLowerCommon Char
    c = Char -> Bool
    isLower' Char
    c
             Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    _mu
             Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    _ordfeminine
             Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    _ordmasculine

    isLower' :: Char -> Bool
    isLower' :: Char -> Bool
    isLower' Char
    c = Char -> Bool
    isAsciiLower Char
    c
              Bool -> Bool -> Bool
    || Char
    _germandbls Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    c Bool -> Bool -> Bool
    && Char
    c Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    _odieresis
              Bool -> Bool -> Bool
    || Char
    _oslash     Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    c Bool -> Bool -> Bool
    && Char
    c Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    _ydieresis

    isUpper :: Char -> Bool
    isUpper :: Char -> Bool
    isUpper Char
    c = Char -> Bool
    isAsciiUpper Char
    c
             Bool -> Bool -> Bool
    || Char
    _Agrave Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    c Bool -> Bool -> Bool
    && Char
    c Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    _Odieresis
             Bool -> Bool -> Bool
    || Char
    _Oslash Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    c Bool -> Bool -> Bool
    && Char
    c Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    _Thorn

    isAlpha :: Char -> Bool
    isAlpha :: Char -> Bool
    isAlpha Char
    c = Char -> Bool
    isLowerCommon Char
    c Bool -> Bool -> Bool
    || Char -> Bool
    isUpper Char
    c

    isAlphaNum :: Char -> Bool
    isAlphaNum :: Char -> Bool
    isAlphaNum Char
    c = Char -> Bool
    isAlpha Char
    c Bool -> Bool -> Bool
    || Char -> Bool
    isNumber Char
    c

    isPrint :: Char -> Bool
    isPrint :: Char -> Bool
    isPrint Char
    c
      | Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    _softhyphen = Bool
    False
    isPrint Char
    c = Char
    _space Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    c Bool -> Bool -> Bool
    && Char
    c Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    '~'
             Bool -> Bool -> Bool
    || Char
    _nbsp  Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    c Bool -> Bool -> Bool
    && Char
    c Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    _ydieresis

    isDigit :: Char -> Bool
    isDigit :: Char -> Bool
    isDigit Char
    c = Char
    '0' Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    c Bool -> Bool -> Bool
    && Char
    c Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    '9'

    isOctDigit :: Char -> Bool
    isOctDigit :: Char -> Bool
    isOctDigit Char
    c = Char
    '0' Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    c Bool -> Bool -> Bool
    && Char
    c Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    '7'

    isHexDigit :: Char -> Bool
    isHexDigit :: Char -> Bool
    isHexDigit Char
    c = Char -> Bool
    isDigit Char
    c
                Bool -> Bool -> Bool
    || Char
    'A' Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    c Bool -> Bool -> Bool
    && Char
    c Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    'F'
                Bool -> Bool -> Bool
    || Char
    'a' Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    c Bool -> Bool -> Bool
    && Char
    c Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    'f'

    isLetter :: Char -> Bool
    isLetter :: Char -> Bool
    isLetter Char
    c = Char -> Bool
    isLowerCommon Char
    c Bool -> Bool -> Bool
    || Char -> Bool
    isUpper Char
    c

    isMark :: Char -> Bool
    isMark :: Char -> Bool
    isMark Char
    _ = Bool
    False

    isNumber :: Char -> Bool
    isNumber :: Char -> Bool
    isNumber Char
    c = Char -> Bool
    isDigit Char
    c
              Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    _s1
              Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    _s2
              Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    _s3
              Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    _1'4
              Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    _1'2
              Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    _3'4

    -- | This function returns 'False' for 167 and 182 in Unicode 6.
    --   But it returns 'True' in Unicode 7.
    isPunctuation :: Char -> Bool
    #if MIN_VERSION_base(4,8,0)
    isPunctuation :: Char -> Bool
    isPunctuation Char
    c = Char
    c Char -> [Char] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [Char
    '\x21',Char
    '\x22',Char
    '\x23',Char
    '\x25',Char
    '\x26',Char
    '\x27',Char
    '\x28',Char
    '\x29',Char
    '\x2a',Char
    '\x2c',Char
    '\x2d',Char
    '\x2e',Char
    '\x2f',Char
    '\x3a',Char
    '\x3b',Char
    '\x3f',Char
    '\x40',Char
    '\x5b',Char
    '\x5c',Char
    '\x5d',Char
    '\x5f',Char
    '\x7b',Char
    '\x7d',Char
    '\xa1',Char
    '\xa7',Char
    '\xab',Char
    '\xb6',Char
    '\xb7',Char
    '\xbb',Char
    '\xbf']
    #else
    isPunctuation c = c `elem` ['\x21','\x22','\x23','\x25','\x26','\x27','\x28','\x29','\x2a','\x2c','\x2d','\x2e','\x2f','\x3a','\x3b','\x3f','\x40','\x5b','\x5c','\x5d','\x5f','\x7b','\x7d','\xa1','\xab','\xb7','\xbb','\xbf']
    #endif

    -- | This function returns 'True' for 167 and 182 in Unicode 6.
    --   But it returns 'False' in Unicode 7.
    isSymbol :: Char -> Bool
    #if MIN_VERSION_base(4,8,0)
    isSymbol :: Char -> Bool
    isSymbol Char
    c = Char
    c Char -> [Char] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [Char
    '\x24',Char
    '\x2b',Char
    '\x3c',Char
    '\x3d',Char
    '\x3e',Char
    '\x5e',Char
    '\x60',Char
    '\x7c',Char
    '\x7e',Char
    '\xa2',Char
    '\xa3',Char
    '\xa4',Char
    '\xa5',Char
    '\xa6',Char
    '\xa8',Char
    '\xa9',Char
    '\xac',Char
    '\xae',Char
    '\xaf',Char
    '\xb0',Char
    '\xb1',Char
    '\xb4',Char
    '\xb8',Char
    '\xd7',Char
    '\xf7']
    #else
    isSymbol c = c `elem` ['\x24','\x2b','\x3c','\x3d','\x3e','\x5e','\x60','\x7c','\x7e','\xa2','\xa3','\xa4','\xa5','\xa6','\xa7','\xa8','\xa9','\xac','\xae','\xaf','\xb0','\xb1','\xb4','\xb6','\xb8','\xd7','\xf7']
    #endif

    isSeparator :: Char -> Bool
    isSeparator :: Char -> Bool
    isSeparator Char
    c = Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    _space
                 Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    _nbsp

    ----------------------------------------------------------------

    isAscii :: Char -> Bool
    isAscii :: Char -> Bool
    isAscii Char
    c = Char
    _nul Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    c Bool -> Bool -> Bool
    && Char
    c Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    _del

    isLatin1 :: Char -> Bool
    #if __GLASGOW_HASKELL__ >= 707
    isLatin1 :: Char -> Bool
    isLatin1 (C# Char#
    c#) = Int# -> Bool
    isTrue# (Char# -> Int#
    ord# Char#
    c# Int# -> Int# -> Int#
    <=# Int#
    0xff#)
    #else
    isLatin1 (C# c#) = ord# c# <=# 0xff#
    #endif

    isAsciiUpper :: Char -> Bool
    isAsciiUpper :: Char -> Bool
    isAsciiUpper Char
    c = Char
    'A' Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    c Bool -> Bool -> Bool
    && Char
    c Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    'Z'

    isAsciiLower :: Char -> Bool
    isAsciiLower :: Char -> Bool
    isAsciiLower Char
    c = Char
    'a' Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    c Bool -> Bool -> Bool
    && Char
    c Char -> Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char
    'z'

    ----------------------------------------------------------------

    -- | Micro sign/mu (0xb5) and small letter Y with diaeresis (0xff) remain the same.
    toUpper :: Char -> Char
    toUpper :: Char -> Char
    toUpper c :: Char
    c@(C# Char#
    c#)
      | Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    _germandbls = Char
    c
      | Char -> Bool
    isLower' Char
    c       = Char# -> Char
    C# (Int# -> Char#
    chr# (Char# -> Int#
    ord# Char#
    c# Int# -> Int# -> Int#
    -# Int#
    32#))
      | Bool
    otherwise        = Char
    c

    toLower :: Char -> Char
    toLower :: Char -> Char
    toLower c :: Char
    c@(C# Char#
    c#)
      | Char -> Bool
    isUpper Char
    c = Char# -> Char
    C# (Int# -> Char#
    chr# (Char# -> Int#
    ord# Char#
    c# Int# -> Int# -> Int#
    +# Int#
    32#))
      | Bool
    otherwise = Char
    c

    -- | Micro sign/mu (0xb5) and small letter Y with diaeresis (0xff) remain the same.
    toTitle :: Char -> Char
    toTitle :: Char -> Char
    toTitle = Char -> Char
    toUpper

    ----------------------------------------------------------------

    _nul, _tab, _lf, _vt, _np, _cr :: Char
    _nul :: Char
    _nul = Char
    '\x00'
    _tab :: Char
    _tab = Char
    '\x09'
    _lf :: Char
    _lf  = Char
    '\x0a'
    _vt :: Char
    _vt  = Char
    '\x0b'
    _np :: Char
    _np  = Char
    '\x0c'
    _cr :: Char
    _cr  = Char
    '\x0d'

    _space, _del, _nbsp :: Char
    _space :: Char
    _space = Char
    '\x20'
    _del :: Char
    _del   = Char
    '\x7f'
    _nbsp :: Char
    _nbsp  = Char
    '\xa0'

    _ordfeminine, _softhyphen, _mu, _ordmasculine :: Char
    _ordfeminine :: Char
    _ordfeminine  = Char
    '\xaa'
    _softhyphen :: Char
    _softhyphen   = Char
    '\xad'
    _mu :: Char
    _mu           = Char
    '\xb5'
    _ordmasculine :: Char
    _ordmasculine = Char
    '\xba'

    _s2, _s3, _s1, _1'4, _1'2, _3'4  :: Char
    _s2 :: Char
    _s2 = Char
    '\xb2'
    _s3 :: Char
    _s3 = Char
    '\xb3'
    _s1 :: Char
    _s1 = Char
    '\xb9'
    _1'4 :: Char
    _1'4 = Char
    '\xbc'
    _1'2 :: Char
    _1'2 = Char
    '\xbd'
    _3'4 :: Char
    _3'4 = Char
    '\xbe'

    _Agrave, _Odieresis, _Oslash, _Thorn :: Char
    _Agrave :: Char
    _Agrave    = Char
    '\xc0'
    _Odieresis :: Char
    _Odieresis = Char
    '\xd6'
    _Oslash :: Char
    _Oslash    = Char
    '\xd8'
    _Thorn :: Char
    _Thorn     = Char
    '\xde'

    _germandbls, _agrave, _odieresis, _oslash, _thorn, _ydieresis :: Char
    _germandbls :: Char
    _germandbls = Char
    '\xdf'
    _agrave :: Char
    _agrave     = Char
    '\xe0'
    _odieresis :: Char
    _odieresis  = Char
    '\xf6'
    _oslash :: Char
    _oslash     = Char
    '\xf8'
    _thorn :: Char
    _thorn      = Char
    '\xfe'
    _ydieresis :: Char
    _ydieresis  = Char
    '\xff'