diff --git a/benchmarks/text-benchmarks.cabal b/benchmarks/text-benchmarks.cabal index 67378715..7716b68c 100644 --- a/benchmarks/text-benchmarks.cabal +++ b/benchmarks/text-benchmarks.cabal @@ -102,6 +102,7 @@ executable text-benchmarks Data.Text.Internal.Builder.Int.Digits Data.Text.Internal.Builder.RealFloat.Functions Data.Text.Internal.ByteStringCompat + Data.Text.Internal.PrimCompat Data.Text.Internal.Encoding.Fusion Data.Text.Internal.Encoding.Fusion.Common Data.Text.Internal.Encoding.Utf16 diff --git a/src/Data/Text/Internal/Encoding/Utf16.hs b/src/Data/Text/Internal/Encoding/Utf16.hs index e5e3c49e..4fe11a62 100644 --- a/src/Data/Text/Internal/Encoding/Utf16.hs +++ b/src/Data/Text/Internal/Encoding/Utf16.hs @@ -1,4 +1,6 @@ -{-# LANGUAGE MagicHash, BangPatterns #-} +{-# LANGUAGE CPP #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE BangPatterns #-} -- | -- Module : Data.Text.Internal.Encoding.Utf16 @@ -26,11 +28,16 @@ module Data.Text.Internal.Encoding.Utf16 import GHC.Exts import GHC.Word (Word16(..)) +#if !MIN_VERSION_base(4,16,0) +-- harmless to import, except for warnings that it is unused. +import Data.Text.Internal.PrimCompat ( word16ToWord# ) +#endif + chr2 :: Word16 -> Word16 -> Char chr2 (W16# a#) (W16# b#) = C# (chr# (upper# +# lower# +# 0x10000#)) where - !x# = word2Int# a# - !y# = word2Int# b# + !x# = word2Int# (word16ToWord# a#) + !y# = word2Int# (word16ToWord# b#) !upper# = uncheckedIShiftL# (x# -# 0xD800#) 10# !lower# = y# -# 0xDC00# {-# INLINE chr2 #-} diff --git a/src/Data/Text/Internal/Encoding/Utf8.hs b/src/Data/Text/Internal/Encoding/Utf8.hs index 5ec469b2..e69113fa 100644 --- a/src/Data/Text/Internal/Encoding/Utf8.hs +++ b/src/Data/Text/Internal/Encoding/Utf8.hs @@ -46,6 +46,11 @@ import Data.Text.Internal.Unsafe.Shift (shiftR) import GHC.Exts import GHC.Word (Word8(..)) +#if !MIN_VERSION_base(4,16,0) +-- harmless to import, except for warnings that it is unused. +import Data.Text.Internal.PrimCompat (word8ToWord#) +#endif + default(Int) between :: Word8 -- ^ byte to check @@ -94,8 +99,8 @@ ord4 c = chr2 :: Word8 -> Word8 -> Char chr2 (W8# x1#) (W8# x2#) = C# (chr# (z1# +# z2#)) where - !y1# = word2Int# x1# - !y2# = word2Int# x2# + !y1# = word2Int# (word8ToWord# x1#) + !y2# = word2Int# (word8ToWord# x2#) !z1# = uncheckedIShiftL# (y1# -# 0xC0#) 6# !z2# = y2# -# 0x80# {-# INLINE chr2 #-} @@ -103,9 +108,9 @@ chr2 (W8# x1#) (W8# x2#) = C# (chr# (z1# +# z2#)) chr3 :: Word8 -> Word8 -> Word8 -> Char chr3 (W8# x1#) (W8# x2#) (W8# x3#) = C# (chr# (z1# +# z2# +# z3#)) where - !y1# = word2Int# x1# - !y2# = word2Int# x2# - !y3# = word2Int# x3# + !y1# = word2Int# (word8ToWord# x1#) + !y2# = word2Int# (word8ToWord# x2#) + !y3# = word2Int# (word8ToWord# x3#) !z1# = uncheckedIShiftL# (y1# -# 0xE0#) 12# !z2# = uncheckedIShiftL# (y2# -# 0x80#) 6# !z3# = y3# -# 0x80# @@ -115,10 +120,10 @@ chr4 :: Word8 -> Word8 -> Word8 -> Word8 -> Char chr4 (W8# x1#) (W8# x2#) (W8# x3#) (W8# x4#) = C# (chr# (z1# +# z2# +# z3# +# z4#)) where - !y1# = word2Int# x1# - !y2# = word2Int# x2# - !y3# = word2Int# x3# - !y4# = word2Int# x4# + !y1# = word2Int# (word8ToWord# x1#) + !y2# = word2Int# (word8ToWord# x2#) + !y3# = word2Int# (word8ToWord# x3#) + !y4# = word2Int# (word8ToWord# x4#) !z1# = uncheckedIShiftL# (y1# -# 0xF0#) 18# !z2# = uncheckedIShiftL# (y2# -# 0x80#) 12# !z3# = uncheckedIShiftL# (y3# -# 0x80#) 6# diff --git a/src/Data/Text/Internal/PrimCompat.hs b/src/Data/Text/Internal/PrimCompat.hs new file mode 100644 index 00000000..2af87c0a --- /dev/null +++ b/src/Data/Text/Internal/PrimCompat.hs @@ -0,0 +1,37 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE MagicHash #-} + +module Data.Text.Internal.PrimCompat + ( word8ToWord# + , wordToWord8# + + , word16ToWord# + , wordToWord16# + + , wordToWord32# + , word32ToWord# + ) where + +#if MIN_VERSION_base(4,16,0) + +import GHC.Base + +#else + +import GHC.Prim (Word#) + +wordToWord8#, word8ToWord# :: Word# -> Word# +wordToWord16#, word16ToWord# :: Word# -> Word# +wordToWord32#, word32ToWord# :: Word# -> Word# +word8ToWord# w = w +word16ToWord# w = w +word32ToWord# w = w +wordToWord8# w = w +wordToWord16# w = w +wordToWord32# w = w +{-# INLINE wordToWord16# #-} +{-# INLINE word16ToWord# #-} +{-# INLINE wordToWord32# #-} +{-# INLINE word32ToWord# #-} + +#endif diff --git a/src/Data/Text/Internal/Unsafe/Char.hs b/src/Data/Text/Internal/Unsafe/Char.hs index d208e3f0..2adaa0d3 100644 --- a/src/Data/Text/Internal/Unsafe/Char.hs +++ b/src/Data/Text/Internal/Unsafe/Char.hs @@ -35,21 +35,22 @@ import Data.Text.Internal.Unsafe.Shift (shiftR) import GHC.Exts (Char(..), Int(..), chr#, ord#, word2Int#) import GHC.Word (Word8(..), Word16(..), Word32(..)) import qualified Data.Text.Array as A +import Data.Text.Internal.PrimCompat ( word8ToWord#, word16ToWord#, word32ToWord# ) ord :: Char -> Int ord (C# c#) = I# (ord# c#) {-# INLINE ord #-} unsafeChr :: Word16 -> Char -unsafeChr (W16# w#) = C# (chr# (word2Int# w#)) +unsafeChr (W16# w#) = C# (chr# (word2Int# (word16ToWord# w#))) {-# INLINE unsafeChr #-} unsafeChr8 :: Word8 -> Char -unsafeChr8 (W8# w#) = C# (chr# (word2Int# w#)) +unsafeChr8 (W8# w#) = C# (chr# (word2Int# (word8ToWord# w#))) {-# INLINE unsafeChr8 #-} unsafeChr32 :: Word32 -> Char -unsafeChr32 (W32# w#) = C# (chr# (word2Int# w#)) +unsafeChr32 (W32# w#) = C# (chr# (word2Int# (word32ToWord# w#))) {-# INLINE unsafeChr32 #-} -- | Write a character into the array at the given offset. Returns diff --git a/tests/text-tests.cabal b/tests/text-tests.cabal index 1c04cc7d..4db42397 100644 --- a/tests/text-tests.cabal +++ b/tests/text-tests.cabal @@ -122,6 +122,7 @@ test-suite tests Data.Text.Internal.Builder.Int.Digits Data.Text.Internal.Builder.RealFloat.Functions Data.Text.Internal.ByteStringCompat + Data.Text.Internal.PrimCompat Data.Text.Internal.Encoding.Fusion Data.Text.Internal.Encoding.Fusion.Common Data.Text.Internal.Encoding.Utf16 diff --git a/text.cabal b/text.cabal index 81e5af05..1d766ab0 100644 --- a/text.cabal +++ b/text.cabal @@ -121,6 +121,7 @@ library Data.Text.Internal.Builder.Int.Digits Data.Text.Internal.Builder.RealFloat.Functions Data.Text.Internal.ByteStringCompat + Data.Text.Internal.PrimCompat Data.Text.Internal.Encoding.Fusion Data.Text.Internal.Encoding.Fusion.Common Data.Text.Internal.Encoding.Utf16 @@ -162,7 +163,7 @@ library base >= 4.3 && < 5, binary >= 0.5 && < 0.9, deepseq >= 1.1 && < 1.5, - ghc-prim >= 0.2 && < 0.8, + ghc-prim >= 0.2 && < 0.9, template-haskell >= 2.5 && < 2.18 if flag(bytestring-builder)