{-# LANGUAGE UnicodeSyntax #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
#if MIN_VERSION_base(4,6,0)
{-# LANGUAGE DeriveGeneric #-}
#endif

module Data.Endian
  ( Endian(..)
  , isLittleEndian
  , isBigEndian
  , EndianSensitive(..)
  , toLittleEndian
  , fromLittleEndian
  , toBigEndian
  , fromBigEndian
  , toEndian
  , fromEndian
  ) where

import Data.Typeable (Typeable)
import Data.Data (Data)
#if MIN_VERSION_base(4,6,0)
import GHC.Generics (Generic)
#endif
import Data.Ix (Ix)
import Data.Int
import Data.Word
import Data.Bits
import Foreign.C.Types
import Foreign.Ptr (IntPtr, WordPtr)
import System.Posix.Types (CSsize)

#include <HsBaseConfig.h>

-- | Endianness.
data Endian = LittleEndian -- ^ Little-endian
            | BigEndian    -- ^ Big-endian
            deriving (Typeable, Typeable Endian
Constr
DataType
Typeable Endian
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Endian -> c Endian)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Endian)
-> (Endian -> Constr)
-> (Endian -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Endian))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Endian))
-> ((forall b. Data b => b -> b) -> Endian -> Endian)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Endian -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Endian -> r)
-> (forall u. (forall d. Data d => d -> u) -> Endian -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Endian -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Endian -> m Endian)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Endian -> m Endian)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Endian -> m Endian)
-> Data Endian
Endian -> Constr
Endian -> DataType
(forall b. Data b => b -> b) -> Endian -> Endian
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Endian -> c Endian
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Endian
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Endian -> u
forall u. (forall d. Data d => d -> u) -> Endian -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Endian -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Endian -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Endian -> m Endian
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Endian -> m Endian
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Endian
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Endian -> c Endian
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Endian)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Endian)
$cBigEndian :: Constr
$cLittleEndian :: Constr
$tEndian :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Endian -> m Endian
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Endian -> m Endian
gmapMp :: (forall d. Data d => d -> m d) -> Endian -> m Endian
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Endian -> m Endian
gmapM :: (forall d. Data d => d -> m d) -> Endian -> m Endian
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Endian -> m Endian
gmapQi :: Int -> (forall d. Data d => d -> u) -> Endian -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Endian -> u
gmapQ :: (forall d. Data d => d -> u) -> Endian -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Endian -> [u]
gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Endian -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Endian -> r
gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Endian -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Endian -> r
gmapT :: (forall b. Data b => b -> b) -> Endian -> Endian
$cgmapT :: (forall b. Data b => b -> b) -> Endian -> Endian
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Endian)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Endian)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c Endian)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Endian)
dataTypeOf :: Endian -> DataType
$cdataTypeOf :: Endian -> DataType
toConstr :: Endian -> Constr
$ctoConstr :: Endian -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Endian
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Endian
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Endian -> c Endian
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Endian -> c Endian
$cp1Data :: Typeable Endian
Data, Int -> Endian -> ShowS
[Endian] -> ShowS
Endian -> String
(Int -> Endian -> ShowS)
-> (Endian -> String) -> ([Endian] -> ShowS) -> Show Endian
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Endian] -> ShowS
$cshowList :: [Endian] -> ShowS
show :: Endian -> String
$cshow :: Endian -> String
showsPrec :: Int -> Endian -> ShowS
$cshowsPrec :: Int -> Endian -> ShowS
Show, ReadPrec [Endian]
ReadPrec Endian
Int -> ReadS Endian
ReadS [Endian]
(Int -> ReadS Endian)
-> ReadS [Endian]
-> ReadPrec Endian
-> ReadPrec [Endian]
-> Read Endian
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Endian]
$creadListPrec :: ReadPrec [Endian]
readPrec :: ReadPrec Endian
$creadPrec :: ReadPrec Endian
readList :: ReadS [Endian]
$creadList :: ReadS [Endian]
readsPrec :: Int -> ReadS Endian
$creadsPrec :: Int -> ReadS Endian
Read,
#if MIN_VERSION_base(4,6,0)
                      (forall x. Endian -> Rep Endian x)
-> (forall x. Rep Endian x -> Endian) -> Generic Endian
forall x. Rep Endian x -> Endian
forall x. Endian -> Rep Endian x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Endian x -> Endian
$cfrom :: forall x. Endian -> Rep Endian x
Generic,
#endif
                      Endian -> Endian -> Bool
(Endian -> Endian -> Bool)
-> (Endian -> Endian -> Bool) -> Eq Endian
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Endian -> Endian -> Bool
$c/= :: Endian -> Endian -> Bool
== :: Endian -> Endian -> Bool
$c== :: Endian -> Endian -> Bool
Eq, Eq Endian
Eq Endian
-> (Endian -> Endian -> Ordering)
-> (Endian -> Endian -> Bool)
-> (Endian -> Endian -> Bool)
-> (Endian -> Endian -> Bool)
-> (Endian -> Endian -> Bool)
-> (Endian -> Endian -> Endian)
-> (Endian -> Endian -> Endian)
-> Ord Endian
Endian -> Endian -> Bool
Endian -> Endian -> Ordering
Endian -> Endian -> Endian
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Endian -> Endian -> Endian
$cmin :: Endian -> Endian -> Endian
max :: Endian -> Endian -> Endian
$cmax :: Endian -> Endian -> Endian
>= :: Endian -> Endian -> Bool
$c>= :: Endian -> Endian -> Bool
> :: Endian -> Endian -> Bool
$c> :: Endian -> Endian -> Bool
<= :: Endian -> Endian -> Bool
$c<= :: Endian -> Endian -> Bool
< :: Endian -> Endian -> Bool
$c< :: Endian -> Endian -> Bool
compare :: Endian -> Endian -> Ordering
$ccompare :: Endian -> Endian -> Ordering
$cp1Ord :: Eq Endian
Ord, Endian
Endian -> Endian -> Bounded Endian
forall a. a -> a -> Bounded a
maxBound :: Endian
$cmaxBound :: Endian
minBound :: Endian
$cminBound :: Endian
Bounded, Int -> Endian
Endian -> Int
Endian -> [Endian]
Endian -> Endian
Endian -> Endian -> [Endian]
Endian -> Endian -> Endian -> [Endian]
(Endian -> Endian)
-> (Endian -> Endian)
-> (Int -> Endian)
-> (Endian -> Int)
-> (Endian -> [Endian])
-> (Endian -> Endian -> [Endian])
-> (Endian -> Endian -> [Endian])
-> (Endian -> Endian -> Endian -> [Endian])
-> Enum Endian
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Endian -> Endian -> Endian -> [Endian]
$cenumFromThenTo :: Endian -> Endian -> Endian -> [Endian]
enumFromTo :: Endian -> Endian -> [Endian]
$cenumFromTo :: Endian -> Endian -> [Endian]
enumFromThen :: Endian -> Endian -> [Endian]
$cenumFromThen :: Endian -> Endian -> [Endian]
enumFrom :: Endian -> [Endian]
$cenumFrom :: Endian -> [Endian]
fromEnum :: Endian -> Int
$cfromEnum :: Endian -> Int
toEnum :: Int -> Endian
$ctoEnum :: Int -> Endian
pred :: Endian -> Endian
$cpred :: Endian -> Endian
succ :: Endian -> Endian
$csucc :: Endian -> Endian
Enum, Ord Endian
Ord Endian
-> ((Endian, Endian) -> [Endian])
-> ((Endian, Endian) -> Endian -> Int)
-> ((Endian, Endian) -> Endian -> Int)
-> ((Endian, Endian) -> Endian -> Bool)
-> ((Endian, Endian) -> Int)
-> ((Endian, Endian) -> Int)
-> Ix Endian
(Endian, Endian) -> Int
(Endian, Endian) -> [Endian]
(Endian, Endian) -> Endian -> Bool
(Endian, Endian) -> Endian -> Int
forall a.
Ord a
-> ((a, a) -> [a])
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Bool)
-> ((a, a) -> Int)
-> ((a, a) -> Int)
-> Ix a
unsafeRangeSize :: (Endian, Endian) -> Int
$cunsafeRangeSize :: (Endian, Endian) -> Int
rangeSize :: (Endian, Endian) -> Int
$crangeSize :: (Endian, Endian) -> Int
inRange :: (Endian, Endian) -> Endian -> Bool
$cinRange :: (Endian, Endian) -> Endian -> Bool
unsafeIndex :: (Endian, Endian) -> Endian -> Int
$cunsafeIndex :: (Endian, Endian) -> Endian -> Int
index :: (Endian, Endian) -> Endian -> Int
$cindex :: (Endian, Endian) -> Endian -> Int
range :: (Endian, Endian) -> [Endian]
$crange :: (Endian, Endian) -> [Endian]
$cp1Ix :: Ord Endian
Ix)

-- | Return 'True' if the supplied value is 'LittleEndian'.
isLittleEndian  Endian  Bool
isLittleEndian :: Endian -> Bool
isLittleEndian Endian
LittleEndian = Bool
True
isLittleEndian Endian
BigEndian    = Bool
False

-- | Return 'True' if the supplied value is 'BigEndian'.
isBigEndian  Endian  Bool
isBigEndian :: Endian -> Bool
isBigEndian Endian
LittleEndian = Bool
False
isBigEndian Endian
BigEndian    = Bool
True

-- | Raw, endian-sensitive data.
class EndianSensitive α where
  -- | Change the endianness of the argument.
  swapEndian  α  α

-- | Convert from the native format to little-endian.
toLittleEndian    EndianSensitive α  α  α
-- | Convert from little-endian to the native format.
fromLittleEndian  EndianSensitive α  α  α
-- | Convert from the native format to big-endian.
toBigEndian       EndianSensitive α  α  α
-- | Convert from big-endian to the native format.
fromBigEndian     EndianSensitive α  α  α

#ifdef WORDS_BIGENDIAN
toLittleEndian   = swapEndian
toBigEndian      = id
#else
toLittleEndian :: α -> α
toLittleEndian   = α -> α
forall a. a -> a
id
toBigEndian :: α -> α
toBigEndian      = α -> α
forall α. EndianSensitive α => α -> α
swapEndian
#endif

fromLittleEndian :: α -> α
fromLittleEndian = α -> α
forall α. EndianSensitive α => α -> α
toLittleEndian
fromBigEndian :: α -> α
fromBigEndian    = α -> α
forall α. EndianSensitive α => α -> α
toBigEndian

{-# INLINE toLittleEndian #-}
{-# INLINE fromLittleEndian #-}
{-# INLINE toBigEndian #-}
{-# INLINE fromBigEndian #-}

-- | Convert from the native format to the specified endianness.
toEndian  EndianSensitive α  Endian  α  α
toEndian :: Endian -> α -> α
toEndian Endian
LittleEndian = α -> α
forall α. EndianSensitive α => α -> α
toLittleEndian
toEndian Endian
BigEndian    = α -> α
forall α. EndianSensitive α => α -> α
toBigEndian

-- | Convert from the specified endianness to the native format.
fromEndian  EndianSensitive α  Endian  α  α
fromEndian :: Endian -> α -> α
fromEndian = Endian -> α -> α
forall α. EndianSensitive α => Endian -> α -> α
toEndian
{-# INLINE fromEndian #-}

instance EndianSensitive α  EndianSensitive [α] where
  swapEndian :: [α] -> [α]
swapEndian = (α -> α) -> [α] -> [α]
forall a b. (a -> b) -> [a] -> [b]
map α -> α
forall α. EndianSensitive α => α -> α
swapEndian

instance EndianSensitive Word16 where
  swapEndian :: Word16 -> Word16
swapEndian = (Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
`rotateR` Int
8)
  {-# INLINE swapEndian #-}

instance EndianSensitive Word32 where
  swapEndian :: Word32 -> Word32
swapEndian Word32
x  =  (Word32
x                  Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftR` Int
24)
               Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. ((Word32
x Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32
0x00FF0000) Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftR` Int
8)
               Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. ((Word32
x Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32
0x0000FF00) Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftL` Int
8)
               Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. (Word32
x                  Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftL` Int
24)
  {-# INLINE swapEndian #-}

instance EndianSensitive Word64 where
  swapEndian :: Word64 -> Word64
swapEndian Word64
x
#if WORD_SIZE_IN_BITS == 32
    =  fromIntegral (swapEndian hi)
   .|. (fromIntegral (swapEndian lo) `shiftL` 32)
      where lo, hi  Word32
            lo = fromIntegral x
            hi = fromIntegral (x `shiftR` 32)
#else
    =  (Word64
x                          Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
56)
   Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. ((Word64
x Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
0x00FF000000000000) Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
40)
   Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. ((Word64
x Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
0x0000FF0000000000) Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
24)
   Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. ((Word64
x Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
0x000000FF00000000) Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
8)
   Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. ((Word64
x Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
0x00000000FF000000) Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
8)
   Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. ((Word64
x Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
0x0000000000FF0000) Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
24)
   Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. ((Word64
x Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
0x000000000000FF00) Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
40)
   Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word64
x                          Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
56)
#endif
  {-# INLINE swapEndian #-}

instance EndianSensitive Int16 where
  swapEndian :: Int16 -> Int16
swapEndian = (Int16 -> Int -> Int16
forall a. Bits a => a -> Int -> a
`rotateR` Int
8)
  {-# INLINE swapEndian #-}

instance EndianSensitive Int32 where
  swapEndian :: Int32 -> Int32
swapEndian = Word32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Int32) -> (Int32 -> Word32) -> Int32 -> Int32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word32 -> Word32
forall α. EndianSensitive α => α -> α
swapEndian  Word32  Word32) (Word32 -> Word32) -> (Int32 -> Word32) -> Int32 -> Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  {-# INLINE swapEndian #-}

instance EndianSensitive Int64 where
  swapEndian :: Int64 -> Int64
swapEndian = Word64 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Int64) -> (Int64 -> Word64) -> Int64 -> Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word64 -> Word64
forall α. EndianSensitive α => α -> α
swapEndian  Word64  Word64) (Word64 -> Word64) -> (Int64 -> Word64) -> Int64 -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  {-# INLINE swapEndian #-}

instance EndianSensitive CShort where
  swapEndian :: CShort -> CShort
swapEndian = Int16 -> CShort
forall a b. (Integral a, Num b) => a -> b
fromIntegral
             (Int16 -> CShort) -> (CShort -> Int16) -> CShort -> CShort
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int16 -> Int16
forall α. EndianSensitive α => α -> α
swapEndian  HTYPE_SHORT  HTYPE_SHORT)
             (Int16 -> Int16) -> (CShort -> Int16) -> CShort -> Int16
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CShort -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  {-# INLINE swapEndian #-}

instance EndianSensitive CUShort where
  swapEndian :: CUShort -> CUShort
swapEndian = Word16 -> CUShort
forall a b. (Integral a, Num b) => a -> b
fromIntegral
             (Word16 -> CUShort) -> (CUShort -> Word16) -> CUShort -> CUShort
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word16 -> Word16
forall α. EndianSensitive α => α -> α
swapEndian  HTYPE_UNSIGNED_SHORT  HTYPE_UNSIGNED_SHORT)
             (Word16 -> Word16) -> (CUShort -> Word16) -> CUShort -> Word16
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CUShort -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  {-# INLINE swapEndian #-}

instance EndianSensitive CInt where
  swapEndian :: CInt -> CInt
swapEndian = Int32 -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral
             (Int32 -> CInt) -> (CInt -> Int32) -> CInt -> CInt
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int32 -> Int32
forall α. EndianSensitive α => α -> α
swapEndian  HTYPE_INT  HTYPE_INT)
             (Int32 -> Int32) -> (CInt -> Int32) -> CInt -> Int32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CInt -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  {-# INLINE swapEndian #-}

instance EndianSensitive CUInt where
  swapEndian :: CUInt -> CUInt
swapEndian = Word32 -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral
             (Word32 -> CUInt) -> (CUInt -> Word32) -> CUInt -> CUInt
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word32 -> Word32
forall α. EndianSensitive α => α -> α
swapEndian  HTYPE_UNSIGNED_INT  HTYPE_UNSIGNED_INT)
             (Word32 -> Word32) -> (CUInt -> Word32) -> CUInt -> Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CUInt -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  {-# INLINE swapEndian #-}

instance EndianSensitive CLong where
  swapEndian :: CLong -> CLong
swapEndian = Int64 -> CLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral
             (Int64 -> CLong) -> (CLong -> Int64) -> CLong -> CLong
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int64 -> Int64
forall α. EndianSensitive α => α -> α
swapEndian  HTYPE_LONG  HTYPE_LONG)
             (Int64 -> Int64) -> (CLong -> Int64) -> CLong -> Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CLong -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  {-# INLINE swapEndian #-}

instance EndianSensitive CULong where
  swapEndian :: CULong -> CULong
swapEndian = Word64 -> CULong
forall a b. (Integral a, Num b) => a -> b
fromIntegral
             (Word64 -> CULong) -> (CULong -> Word64) -> CULong -> CULong
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word64 -> Word64
forall α. EndianSensitive α => α -> α
swapEndian  HTYPE_UNSIGNED_LONG  HTYPE_UNSIGNED_LONG)
             (Word64 -> Word64) -> (CULong -> Word64) -> CULong -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CULong -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  {-# INLINE swapEndian #-}

#ifdef HAVE_LONG_LONG
instance EndianSensitive CLLong where
  swapEndian :: CLLong -> CLLong
swapEndian = Int64 -> CLLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral
             (Int64 -> CLLong) -> (CLLong -> Int64) -> CLLong -> CLLong
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int64 -> Int64
forall α. EndianSensitive α => α -> α
swapEndian  HTYPE_LONG_LONG  HTYPE_LONG_LONG)
             (Int64 -> Int64) -> (CLLong -> Int64) -> CLLong -> Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CLLong -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  {-# INLINE swapEndian #-}

instance EndianSensitive CULLong where
  swapEndian :: CULLong -> CULLong
swapEndian = Word64 -> CULLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral
             (Word64 -> CULLong) -> (CULLong -> Word64) -> CULLong -> CULLong
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word64 -> Word64
forall α. EndianSensitive α => α -> α
swapEndian  HTYPE_UNSIGNED_LONG_LONG
                            HTYPE_UNSIGNED_LONG_LONG)
             (Word64 -> Word64) -> (CULLong -> Word64) -> CULLong -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CULLong -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  {-# INLINE swapEndian #-}
#endif

instance EndianSensitive CSize where
  swapEndian :: CSize -> CSize
swapEndian = Word64 -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral
             (Word64 -> CSize) -> (CSize -> Word64) -> CSize -> CSize
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word64 -> Word64
forall α. EndianSensitive α => α -> α
swapEndian  HTYPE_SIZE_T  HTYPE_SIZE_T)
             (Word64 -> Word64) -> (CSize -> Word64) -> CSize -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CSize -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  {-# INLINE swapEndian #-}

instance EndianSensitive CSsize where
  swapEndian :: CSsize -> CSsize
swapEndian = Int64 -> CSsize
forall a b. (Integral a, Num b) => a -> b
fromIntegral
             (Int64 -> CSsize) -> (CSsize -> Int64) -> CSsize -> CSsize
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int64 -> Int64
forall α. EndianSensitive α => α -> α
swapEndian  HTYPE_SSIZE_T  HTYPE_SSIZE_T)
             (Int64 -> Int64) -> (CSsize -> Int64) -> CSsize -> Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CSsize -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  {-# INLINE swapEndian #-}

instance EndianSensitive CUIntPtr where
  swapEndian :: CUIntPtr -> CUIntPtr
swapEndian = Word64 -> CUIntPtr
forall a b. (Integral a, Num b) => a -> b
fromIntegral
             (Word64 -> CUIntPtr)
-> (CUIntPtr -> Word64) -> CUIntPtr -> CUIntPtr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word64 -> Word64
forall α. EndianSensitive α => α -> α
swapEndian  HTYPE_UINTPTR_T  HTYPE_UINTPTR_T)
             (Word64 -> Word64) -> (CUIntPtr -> Word64) -> CUIntPtr -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CUIntPtr -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  {-# INLINE swapEndian #-}

instance EndianSensitive CIntPtr where
  swapEndian :: CIntPtr -> CIntPtr
swapEndian = Int64 -> CIntPtr
forall a b. (Integral a, Num b) => a -> b
fromIntegral
             (Int64 -> CIntPtr) -> (CIntPtr -> Int64) -> CIntPtr -> CIntPtr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int64 -> Int64
forall α. EndianSensitive α => α -> α
swapEndian  HTYPE_INTPTR_T  HTYPE_INTPTR_T)
             (Int64 -> Int64) -> (CIntPtr -> Int64) -> CIntPtr -> Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CIntPtr -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  {-# INLINE swapEndian #-}

instance EndianSensitive CPtrdiff where
  swapEndian :: CPtrdiff -> CPtrdiff
swapEndian = Int64 -> CPtrdiff
forall a b. (Integral a, Num b) => a -> b
fromIntegral
             (Int64 -> CPtrdiff) -> (CPtrdiff -> Int64) -> CPtrdiff -> CPtrdiff
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int64 -> Int64
forall α. EndianSensitive α => α -> α
swapEndian  HTYPE_PTRDIFF_T  HTYPE_PTRDIFF_T)
             (Int64 -> Int64) -> (CPtrdiff -> Int64) -> CPtrdiff -> Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CPtrdiff -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  {-# INLINE swapEndian #-}

instance EndianSensitive CUIntMax where
  swapEndian :: CUIntMax -> CUIntMax
swapEndian = Word64 -> CUIntMax
forall a b. (Integral a, Num b) => a -> b
fromIntegral
             (Word64 -> CUIntMax)
-> (CUIntMax -> Word64) -> CUIntMax -> CUIntMax
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word64 -> Word64
forall α. EndianSensitive α => α -> α
swapEndian  HTYPE_UINTMAX_T  HTYPE_UINTMAX_T)
             (Word64 -> Word64) -> (CUIntMax -> Word64) -> CUIntMax -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CUIntMax -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  {-# INLINE swapEndian #-}

instance EndianSensitive CIntMax where
  swapEndian :: CIntMax -> CIntMax
swapEndian = Int64 -> CIntMax
forall a b. (Integral a, Num b) => a -> b
fromIntegral
             (Int64 -> CIntMax) -> (CIntMax -> Int64) -> CIntMax -> CIntMax
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int64 -> Int64
forall α. EndianSensitive α => α -> α
swapEndian  HTYPE_INTMAX_T  HTYPE_INTMAX_T)
             (Int64 -> Int64) -> (CIntMax -> Int64) -> CIntMax -> Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CIntMax -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  {-# INLINE swapEndian #-}

instance EndianSensitive WordPtr where
  swapEndian :: WordPtr -> WordPtr
swapEndian = Word64 -> WordPtr
forall a b. (Integral a, Num b) => a -> b
fromIntegral
             (Word64 -> WordPtr) -> (WordPtr -> Word64) -> WordPtr -> WordPtr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word64 -> Word64
forall α. EndianSensitive α => α -> α
swapEndian  HTYPE_UINTPTR_T  HTYPE_UINTPTR_T)
             (Word64 -> Word64) -> (WordPtr -> Word64) -> WordPtr -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WordPtr -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  {-# INLINE swapEndian #-}

instance EndianSensitive IntPtr where
  swapEndian :: IntPtr -> IntPtr
swapEndian = Int64 -> IntPtr
forall a b. (Integral a, Num b) => a -> b
fromIntegral
             (Int64 -> IntPtr) -> (IntPtr -> Int64) -> IntPtr -> IntPtr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int64 -> Int64
forall α. EndianSensitive α => α -> α
swapEndian  HTYPE_INTPTR_T  HTYPE_INTPTR_T)
             (Int64 -> Int64) -> (IntPtr -> Int64) -> IntPtr -> Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntPtr -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  {-# INLINE swapEndian #-}

#ifdef HTYPE_WCHAR_T
instance EndianSensitive CWchar where
  swapEndian :: CWchar -> CWchar
swapEndian = Int32 -> CWchar
forall a b. (Integral a, Num b) => a -> b
fromIntegral
             (Int32 -> CWchar) -> (CWchar -> Int32) -> CWchar -> CWchar
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int32 -> Int32
forall α. EndianSensitive α => α -> α
swapEndian  HTYPE_WCHAR_T  HTYPE_WCHAR_T)
             (Int32 -> Int32) -> (CWchar -> Int32) -> CWchar -> Int32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CWchar -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  {-# INLINE swapEndian #-}
#endif

#ifdef HTYPE_WINT_T
instance EndianSensitive CWint where
  swapEndian = fromIntegral
             . (swapEndian  HTYPE_WINT_T  HTYPE_WINT_T)
             . fromIntegral
  {-# INLINE swapEndian #-}
#endif