1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeOperators #-}
-- |
-- Module : Basement.Cast
-- License : BSD-style
-- Maintainer : Haskell Foundation
--
module Basement.Cast
( Cast(..)
) where
#include "MachDeps.h"
import qualified Basement.Block.Base as Block
import Basement.Compat.Base
import Basement.Compat.Natural
import Basement.Compat.Primitive
import Basement.Numerical.Number
import Basement.Numerical.Conversion
import Basement.PrimType
import Data.Proxy (Proxy(..))
import GHC.Int
import GHC.Prim
import GHC.Types
import GHC.ST
import GHC.Word
-- | `Cast` an object of type a to b.
--
-- Do not add instance of this class if the source type is not of the same
-- size of the destination type. Also keep in mind this is casting a value
-- of a given type into a destination type. The value won't be changed to
-- fit the destination represention.
--
-- If you wish to convert a value of a given type into another type, look at
-- `From` and `TryFrom`.
--
-- @
-- cast (-10 :: Int) :: Word === 18446744073709551606
-- @
--
class Cast source destination where
cast :: source -> destination
default cast :: ( PrimType source
, PrimType destination
, PrimSize source ~ PrimSize destination
)
=> source -> destination
cast a = runST $ do
mba <- Block.new 1
Block.unsafeWrite mba 0 a
Block.unsafeRead (Block.unsafeRecast mba) 0
instance Cast Int8 Word8 where
cast (I8# i) = W8# (wordToWord8# (int2Word# (int8ToInt# i)))
instance Cast Int16 Word16 where
cast (I16# i) = W16# (wordToWord16# (int2Word# (int16ToInt# i)))
instance Cast Int32 Word32 where
cast (I32# i) = W32# (wordToWord32# (int2Word# (int32ToInt# i)))
instance Cast Int64 Word64 where
cast = int64ToWord64
instance Cast Int Word where
cast (I# i) = W# (int2Word# i)
instance Cast Word8 Int8 where
cast (W8# i) = I8# (intToInt8# (word2Int# (word8ToWord# i)))
instance Cast Word16 Int16 where
cast (W16# i) = I16# (intToInt16# (word2Int# (word16ToWord# i)))
instance Cast Word32 Int32 where
cast (W32# i) = I32# (intToInt32# (word2Int# (word32ToWord# i)))
instance Cast Word64 Int64 where
cast = word64ToInt64
instance Cast Word Int where
cast (W# w) = I# (word2Int# w)
#if WORD_SIZE_IN_BITS == 64
#if __GLASGOW_HASKELL__ >= 904
instance Cast Word Word64 where
cast (W# w) = W64# (wordToWord64# w)
instance Cast Word64 Word where
cast (W64# w) = W# (GHC.Prim.word64ToWord# w)
instance Cast Word Int64 where
cast (W# w) = I64# (intToInt64# (word2Int# w))
instance Cast Int64 Word where
cast (I64# i) = W# (int2Word# (int64ToInt# i))
instance Cast Int Int64 where
cast (I# i) = I64# (intToInt64# i)
instance Cast Int64 Int where
cast (I64# i) = I# (int64ToInt# i)
instance Cast Int Word64 where
cast (I# i) = W64# (wordToWord64# (int2Word# i))
instance Cast Word64 Int where
cast (W64# w) = I# (word2Int# (GHC.Prim.word64ToWord# w))
#else
instance Cast Word Word64 where
cast (W# w) = W64# w
instance Cast Word64 Word where
cast (W64# w) = W# w
instance Cast Word Int64 where
cast (W# w) = I64# (word2Int# w)
instance Cast Int64 Word where
cast (I64# i) = W# (int2Word# i)
instance Cast Int Int64 where
cast (I# i) = I64# i
instance Cast Int64 Int where
cast (I64# i) = I# i
instance Cast Int Word64 where
cast (I# i) = W64# (int2Word# i)
instance Cast Word64 Int where
cast (W64# w) = I# (word2Int# w)
#endif
#else
instance Cast Word Word32 where
cast (W# w) = W32# (wordToWord32# w)
instance Cast Word32 Word where
cast (W32# w) = W# (word32ToWord# w)
instance Cast Word Int32 where
cast (W# w) = I32# (intToInt32# (word2Int# w))
instance Cast Int32 Word where
cast (I32# i) = W# (int2Word# (int32ToInt# i))
instance Cast Int Int32 where
cast (I# i) = I32# (intToInt32# i)
instance Cast Int32 Int where
cast (I32# i) = I# (int32ToInt# i)
instance Cast Int Word32 where
cast (I# i) = W32# (wordToWord32# (int2Word# i))
instance Cast Word32 Int where
cast (W32# w) = I# (word2Int# (word32ToWord# w))
#endif
instance Cast (Block.Block a) (Block.Block Word8) where
cast (Block.Block ba) = Block.Block ba
|