{-# 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'