{-# 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 forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c forall a. Ord a => a -> a -> Bool
<= Char
'\x1f'
           Bool -> Bool -> Bool
|| Char
_del forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c forall a. Ord a => a -> a -> Bool
<= Char
'\x9f'

isSpace :: Char -> Bool
isSpace :: Char -> Bool
isSpace Char
c = Char
c forall a. Eq a => a -> a -> Bool
== Char
_space
         Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
_tab
         Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
_lf
         Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
_cr
         Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
_np
         Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
_vt
         Bool -> Bool -> Bool
|| Char
c 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 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 forall a. Eq a => a -> a -> Bool
== Char
_mu
         Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
_ordfeminine
         Bool -> Bool -> Bool
|| Char
c 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 forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c forall a. Ord a => a -> a -> Bool
<= Char
_odieresis
          Bool -> Bool -> Bool
|| Char
_oslash     forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c 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 forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c forall a. Ord a => a -> a -> Bool
<= Char
_Odieresis
         Bool -> Bool -> Bool
|| Char
_Oslash forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c 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 forall a. Eq a => a -> a -> Bool
== Char
_softhyphen = Bool
False
isPrint Char
c = Char
_space forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c forall a. Ord a => a -> a -> Bool
<= Char
'~'
         Bool -> Bool -> Bool
|| Char
_nbsp  forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c forall a. Ord a => a -> a -> Bool
<= Char
_ydieresis

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

isOctDigit :: Char -> Bool
isOctDigit :: Char -> Bool
isOctDigit Char
c = Char
'0' forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c 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' forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c forall a. Ord a => a -> a -> Bool
<= Char
'F'
            Bool -> Bool -> Bool
|| Char
'a' forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c 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 forall a. Eq a => a -> a -> Bool
== Char
_s1
          Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
_s2
          Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
_s3
          Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
_1'4
          Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
_1'2
          Bool -> Bool -> Bool
|| Char
c 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 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 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 forall a. Eq a => a -> a -> Bool
== Char
_space
             Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
_nbsp

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

isAscii :: Char -> Bool
isAscii :: Char -> Bool
isAscii Char
c = Char
_nul forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c 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' forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c forall a. Ord a => a -> a -> Bool
<= Char
'Z'

isAsciiLower :: Char -> Bool
isAsciiLower :: Char -> Bool
isAsciiLower Char
c = Char
'a' forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c 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 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'