-- GENERATED by C->Haskell Compiler, version 0.28.7 Switcheroo, 25 November 2017 (Haskell)
-- Edit the ORIGNAL .chs file instead!


{-# LINE 1 "lib/CPython/Protocols/Sequence.chs" #-}
{-# LANGUAGE ForeignFunctionInterface #-}

-- Copyright (C) 2009 John Millikin <jmillikin@gmail.com>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.

module CPython.Protocols.Sequence
  ( Sequence (..)
  , SomeSequence
  , castToSequence
  , length
  , append
  , repeat
  , inPlaceAppend
  , inPlaceRepeat
  , getItem
  , setItem
  , deleteItem
  , getSlice
  , setSlice
  , deleteSlice
  , count
  , contains
  , index
  , toList
  , toTuple
  , fast
  ) where
import qualified Foreign.C.Types as C2HSImp
import qualified Foreign.Ptr as C2HSImp





import           Prelude hiding (repeat, length)
import           Data.Text (Text)

import           CPython.Internal
import           CPython.Types.ByteArray (ByteArray)
import           CPython.Types.Bytes (Bytes)
import           CPython.Types.Unicode (Unicode)

instance Sequence ByteArray where
  toSequence :: ByteArray -> SomeSequence
toSequence = ByteArray -> SomeSequence
forall a. Object a => a -> SomeSequence
unsafeCastToSequence

instance Sequence Bytes where
  toSequence :: Bytes -> SomeSequence
toSequence = Bytes -> SomeSequence
forall a. Object a => a -> SomeSequence
unsafeCastToSequence

instance Sequence List where
  toSequence :: List -> SomeSequence
toSequence = List -> SomeSequence
forall a. Object a => a -> SomeSequence
unsafeCastToSequence

instance Sequence Tuple where
  toSequence :: Tuple -> SomeSequence
toSequence = Tuple -> SomeSequence
forall a. Object a => a -> SomeSequence
unsafeCastToSequence

instance Sequence Unicode where
  toSequence :: Unicode -> SomeSequence
toSequence = Unicode -> SomeSequence
forall a. Object a => a -> SomeSequence
unsafeCastToSequence

-- | Attempt to convert an object to a generic 'Sequence'. If the object does
-- not implement the sequence protocol, returns 'Nothing'.
castToSequence :: Object a => a -> IO (Maybe SomeSequence)
castToSequence :: a -> IO (Maybe SomeSequence)
castToSequence obj :: a
obj =
  a -> (Ptr () -> IO (Maybe SomeSequence)) -> IO (Maybe SomeSequence)
forall obj a b. Object obj => obj -> (Ptr a -> IO b) -> IO b
withObject a
obj ((Ptr () -> IO (Maybe SomeSequence)) -> IO (Maybe SomeSequence))
-> (Ptr () -> IO (Maybe SomeSequence)) -> IO (Maybe SomeSequence)
forall a b. (a -> b) -> a -> b
$ \objPtr :: Ptr ()
objPtr -> do
  Bool
isSequence <- (CInt -> Bool) -> IO CInt -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CInt -> Bool
cToBool (IO CInt -> IO Bool) -> IO CInt -> IO Bool
forall a b. (a -> b) -> a -> b
$ Ptr () -> IO CInt
pySequenceCheck Ptr ()
objPtr
  Maybe SomeSequence -> IO (Maybe SomeSequence)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe SomeSequence -> IO (Maybe SomeSequence))
-> Maybe SomeSequence -> IO (Maybe SomeSequence)
forall a b. (a -> b) -> a -> b
$ if Bool
isSequence
    then SomeSequence -> Maybe SomeSequence
forall a. a -> Maybe a
Just (SomeSequence -> Maybe SomeSequence)
-> SomeSequence -> Maybe SomeSequence
forall a b. (a -> b) -> a -> b
$ a -> SomeSequence
forall a. Object a => a -> SomeSequence
unsafeCastToSequence a
obj
    else Maybe SomeSequence
forall a. Maybe a
Nothing

length :: Sequence self => (self) -> IO ((Integer))
length :: self -> IO Integer
length a1 :: self
a1 =
  self -> (Ptr () -> IO Integer) -> IO Integer
forall obj a b. Object obj => obj -> (Ptr a -> IO b) -> IO b
withObject self
a1 ((Ptr () -> IO Integer) -> IO Integer)
-> (Ptr () -> IO Integer) -> IO Integer
forall a b. (a -> b) -> a -> b
$ \a1' :: Ptr ()
a1' -> 
  Ptr () -> IO CLong
length'_ Ptr ()
a1' IO CLong -> (CLong -> IO Integer) -> IO Integer
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \res :: CLong
res ->
  CLong -> IO Integer
forall a. Integral a => a -> IO Integer
checkIntReturn CLong
res IO Integer -> (Integer -> IO Integer) -> IO Integer
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \res' :: Integer
res' ->
  Integer -> IO Integer
forall (m :: * -> *) a. Monad m => a -> m a
return (Integer
res')

{-# LINE 79 "lib/CPython/Protocols/Sequence.chs" #-}


append :: (Sequence a, Sequence b) => (a) -> (b) -> IO ((SomeSequence))
append a1 a2 =
  withObject a1 $ \a1' -> 
  withObject a2 $ \a2' -> 
  append'_ a1' a2' >>= \res ->
  stealObject res >>= \res' ->
  return (res')

{-# LINE 85 "lib/CPython/Protocols/Sequence.chs" #-}


repeat :: Sequence a => (a) -> (Integer) -> IO ((a))
repeat a1 a2 =
  withObject a1 $ \a1' -> 
  let {a2' = fromIntegral a2} in 
  repeat'_ a1' a2' >>= \res ->
  stealObject res >>= \res' ->
  return (res')

{-# LINE 91 "lib/CPython/Protocols/Sequence.chs" #-}


inPlaceAppend :: (Sequence a, Sequence b) => (a) -> (b) -> IO ((SomeSequence))
inPlaceAppend a1 a2 =
  withObject a1 $ \a1' -> 
  withObject a2 $ \a2' -> 
  inPlaceAppend'_ a1' a2' >>= \res ->
  stealObject res >>= \res' ->
  return (res')

{-# LINE 97 "lib/CPython/Protocols/Sequence.chs" #-}


inPlaceRepeat :: Sequence a => (a) -> (Integer) -> IO ((a))
inPlaceRepeat a1 a2 =
  withObject a1 $ \a1' -> 
  let {a2' = fromIntegral a2} in 
  inPlaceRepeat'_ a1' a2' >>= \res ->
  stealObject res >>= \res' ->
  return (res')

{-# LINE 103 "lib/CPython/Protocols/Sequence.chs" #-}


getItem :: Sequence self => (self) -> (Integer) -> IO ((SomeObject))
getItem a1 a2 =
  withObject a1 $ \a1' -> 
  let {a2' = fromIntegral a2} in 
  getItem'_ a1' a2' >>= \res ->
  stealObject res >>= \res' ->
  return (res')

{-# LINE 109 "lib/CPython/Protocols/Sequence.chs" #-}


setItem :: (Sequence self, Object v) => (self) -> (Integer) -> (v) -> IO ((()))
setItem a1 a2 a3 =
  withObject a1 $ \a1' -> 
  let {a2' = fromIntegral a2} in 
  withObject a3 $ \a3' -> 
  setItem'_ a1' a2' a3' >>= \res ->
  checkStatusCode res >>= \res' ->
  return (res')

{-# LINE 116 "lib/CPython/Protocols/Sequence.chs" #-}


deleteItem :: Sequence self => (self) -> (Integer) -> IO ((()))
deleteItem a1 a2 =
  withObject a1 $ \a1' -> 
  let {a2' = fromIntegral a2} in 
  deleteItem'_ a1' a2' >>= \res ->
  checkStatusCode res >>= \res' ->
  return (res')

{-# LINE 122 "lib/CPython/Protocols/Sequence.chs" #-}


getSlice :: Sequence self => (self) -> (Integer) -> (Integer) -> IO ((SomeObject))
getSlice a1 a2 a3 =
  withObject a1 $ \a1' -> 
  let {a2' = fromIntegral a2} in 
  let {a3' = fromIntegral a3} in 
  getSlice'_ a1' a2' a3' >>= \res ->
  stealObject res >>= \res' ->
  return (res')

{-# LINE 129 "lib/CPython/Protocols/Sequence.chs" #-}


setSlice :: (Sequence self, Object v) => (self) -> (Integer) -> (Integer) -> (v) -> IO ((()))
setSlice a1 a2 a3 a4 =
  withObject a1 $ \a1' -> 
  let {a2' = fromIntegral a2} in 
  let {a3' = fromIntegral a3} in 
  withObject a4 $ \a4' -> 
  setSlice'_ a1' a2' a3' a4' >>= \res ->
  checkStatusCode res >>= \res' ->
  return (res')

{-# LINE 137 "lib/CPython/Protocols/Sequence.chs" #-}


deleteSlice :: Sequence self => (self) -> (Integer) -> (Integer) -> IO ((()))
deleteSlice a1 a2 a3 =
  withObject a1 $ \a1' -> 
  let {a2' = fromIntegral a2} in 
  let {a3' = fromIntegral a3} in 
  deleteSlice'_ a1' a2' a3' >>= \res ->
  checkStatusCode res >>= \res' ->
  return (res')

{-# LINE 144 "lib/CPython/Protocols/Sequence.chs" #-}


count :: (Sequence self, Object v) => (self) -> (v) -> IO ((Integer))
count a1 a2 =
  withObject a1 $ \a1' -> 
  withObject a2 $ \a2' -> 
  count'_ a1' a2' >>= \res ->
  checkIntReturn res >>= \res' ->
  return (res')

{-# LINE 150 "lib/CPython/Protocols/Sequence.chs" #-}


contains :: (Sequence self, Object v) => (self) -> (v) -> IO ((Bool))
contains a1 a2 =
  withObject a1 $ \a1' -> 
  withObject a2 $ \a2' -> 
  contains'_ a1' a2' >>= \res ->
  checkBoolReturn res >>= \res' ->
  return (res')

{-# LINE 156 "lib/CPython/Protocols/Sequence.chs" #-}


-- | Return the first index /i/ for which @self[i] == v@. This is equivalent
-- to the Python expression @self.index(v)@.
index :: (Sequence self, Object v) => (self) -> (v) -> IO ((Integer))
index :: self -> v -> IO Integer
index a1 :: self
a1 a2 :: v
a2 =
  self -> (Ptr () -> IO Integer) -> IO Integer
forall obj a b. Object obj => obj -> (Ptr a -> IO b) -> IO b
withObject self
a1 ((Ptr () -> IO Integer) -> IO Integer)
-> (Ptr () -> IO Integer) -> IO Integer
forall a b. (a -> b) -> a -> b
$ \a1' :: Ptr ()
a1' -> 
  v -> (Ptr () -> IO Integer) -> IO Integer
forall obj a b. Object obj => obj -> (Ptr a -> IO b) -> IO b
withObject v
a2 ((Ptr () -> IO Integer) -> IO Integer)
-> (Ptr () -> IO Integer) -> IO Integer
forall a b. (a -> b) -> a -> b
$ \a2' :: Ptr ()
a2' -> 
  Ptr () -> Ptr () -> IO CLong
index'_ Ptr ()
a1' Ptr ()
a2' IO CLong -> (CLong -> IO Integer) -> IO Integer
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \res :: CLong
res ->
  CLong -> IO Integer
forall a. Integral a => a -> IO Integer
checkIntReturn CLong
res IO Integer -> (Integer -> IO Integer) -> IO Integer
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \res' :: Integer
res' ->
  Integer -> IO Integer
forall (m :: * -> *) a. Monad m => a -> m a
return (Integer
res')

{-# LINE 164 "lib/CPython/Protocols/Sequence.chs" #-}


-- | Return a list object with the same contents as the arbitrary sequence
-- /seq/. The returned list is guaranteed to be new.
toList :: Sequence seq => (seq) -> IO ((List))
toList :: seq -> IO List
toList a1 :: seq
a1 =
  seq -> (Ptr () -> IO List) -> IO List
forall obj a b. Object obj => obj -> (Ptr a -> IO b) -> IO b
withObject seq
a1 ((Ptr () -> IO List) -> IO List) -> (Ptr () -> IO List) -> IO List
forall a b. (a -> b) -> a -> b
$ \a1' :: Ptr ()
a1' -> 
  Ptr () -> IO (Ptr ())
toList'_ Ptr ()
a1' IO (Ptr ()) -> (Ptr () -> IO List) -> IO List
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \res :: Ptr ()
res ->
  Ptr () -> IO List
forall obj a. Object obj => Ptr a -> IO obj
stealObject Ptr ()
res IO List -> (List -> IO List) -> IO List
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \res' :: List
res' ->
  List -> IO List
forall (m :: * -> *) a. Monad m => a -> m a
return (List
res')

{-# LINE 171 "lib/CPython/Protocols/Sequence.chs" #-}


-- | Return a tuple object with the same contents as the arbitrary sequence
-- /seq/. If /seq/ is already a tuple, it is re-used rather than copied.
toTuple :: Sequence seq => (seq) -> IO ((Tuple))
toTuple :: seq -> IO Tuple
toTuple a1 :: seq
a1 =
  seq -> (Ptr () -> IO Tuple) -> IO Tuple
forall obj a b. Object obj => obj -> (Ptr a -> IO b) -> IO b
withObject seq
a1 ((Ptr () -> IO Tuple) -> IO Tuple)
-> (Ptr () -> IO Tuple) -> IO Tuple
forall a b. (a -> b) -> a -> b
$ \a1' :: Ptr ()
a1' -> 
  Ptr () -> IO (Ptr ())
toTuple'_ Ptr ()
a1' IO (Ptr ()) -> (Ptr () -> IO Tuple) -> IO Tuple
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \res :: Ptr ()
res ->
  Ptr () -> IO Tuple
forall obj a. Object obj => Ptr a -> IO obj
stealObject Ptr ()
res IO Tuple -> (Tuple -> IO Tuple) -> IO Tuple
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \res' :: Tuple
res' ->
  Tuple -> IO Tuple
forall (m :: * -> *) a. Monad m => a -> m a
return (Tuple
res')

{-# LINE 178 "lib/CPython/Protocols/Sequence.chs" #-}


-- | Returns the sequence /seq/ as a tuple, unless it is already a tuple or
-- list, in which case /seq/ is returned. If an error occurs, throws
-- @TypeError@ with the given text as the exception text.
fast :: Sequence seq => (seq) -> (Text) -> IO ((SomeSequence))
fast :: seq -> Text -> IO SomeSequence
fast a1 :: seq
a1 a2 :: Text
a2 =
  seq -> (Ptr () -> IO SomeSequence) -> IO SomeSequence
forall obj a b. Object obj => obj -> (Ptr a -> IO b) -> IO b
withObject seq
a1 ((Ptr () -> IO SomeSequence) -> IO SomeSequence)
-> (Ptr () -> IO SomeSequence) -> IO SomeSequence
forall a b. (a -> b) -> a -> b
$ \a1' :: Ptr ()
a1' -> 
  Text -> (CString -> IO SomeSequence) -> IO SomeSequence
forall a. Text -> (CString -> IO a) -> IO a
withText Text
a2 ((CString -> IO SomeSequence) -> IO SomeSequence)
-> (CString -> IO SomeSequence) -> IO SomeSequence
forall a b. (a -> b) -> a -> b
$ \a2' :: CString
a2' -> 
  Ptr () -> CString -> IO (Ptr ())
fast'_ Ptr ()
a1' CString
a2' IO (Ptr ()) -> (Ptr () -> IO SomeSequence) -> IO SomeSequence
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \res :: Ptr ()
res ->
  Ptr () -> IO SomeSequence
forall obj a. Object obj => Ptr a -> IO obj
stealObject Ptr ()
res IO SomeSequence
-> (SomeSequence -> IO SomeSequence) -> IO SomeSequence
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \res' :: SomeSequence
res' ->
  SomeSequence -> IO SomeSequence
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeSequence
res')

{-# LINE 187 "lib/CPython/Protocols/Sequence.chs" #-}


foreign import ccall safe "CPython/Protocols/Sequence.chs.h PySequence_Check"
  pySequenceCheck :: ((C2HSImp.Ptr ()) -> (IO C2HSImp.CInt))

foreign import ccall safe "CPython/Protocols/Sequence.chs.h PySequence_Size"
  length'_ :: ((C2HSImp.Ptr ()) -> (IO C2HSImp.CLong))

foreign import ccall safe "CPython/Protocols/Sequence.chs.h PySequence_Concat"
  append'_ :: ((C2HSImp.Ptr ()) -> ((C2HSImp.Ptr ()) -> (IO (C2HSImp.Ptr ()))))

foreign import ccall safe "CPython/Protocols/Sequence.chs.h PySequence_Repeat"
  repeat'_ :: ((C2HSImp.Ptr ()) -> (C2HSImp.CLong -> (IO (C2HSImp.Ptr ()))))

foreign import ccall safe "CPython/Protocols/Sequence.chs.h PySequence_InPlaceConcat"
  inPlaceAppend'_ :: ((C2HSImp.Ptr ()) -> ((C2HSImp.Ptr ()) -> (IO (C2HSImp.Ptr ()))))

foreign import ccall safe "CPython/Protocols/Sequence.chs.h PySequence_InPlaceRepeat"
  inPlaceRepeat'_ :: ((C2HSImp.Ptr ()) -> (C2HSImp.CLong -> (IO (C2HSImp.Ptr ()))))

foreign import ccall safe "CPython/Protocols/Sequence.chs.h PySequence_GetItem"
  getItem'_ :: ((C2HSImp.Ptr ()) -> (C2HSImp.CLong -> (IO (C2HSImp.Ptr ()))))

foreign import ccall safe "CPython/Protocols/Sequence.chs.h PySequence_SetItem"
  setItem'_ :: ((C2HSImp.Ptr ()) -> (C2HSImp.CLong -> ((C2HSImp.Ptr ()) -> (IO C2HSImp.CInt))))

foreign import ccall safe "CPython/Protocols/Sequence.chs.h PySequence_DelItem"
  deleteItem'_ :: ((C2HSImp.Ptr ()) -> (C2HSImp.CLong -> (IO C2HSImp.CInt)))

foreign import ccall safe "CPython/Protocols/Sequence.chs.h PySequence_GetSlice"
  getSlice'_ :: ((C2HSImp.Ptr ()) -> (C2HSImp.CLong -> (C2HSImp.CLong -> (IO (C2HSImp.Ptr ())))))

foreign import ccall safe "CPython/Protocols/Sequence.chs.h PySequence_SetSlice"
  setSlice'_ :: ((C2HSImp.Ptr ()) -> (C2HSImp.CLong -> (C2HSImp.CLong -> ((C2HSImp.Ptr ()) -> (IO C2HSImp.CInt)))))

foreign import ccall safe "CPython/Protocols/Sequence.chs.h PySequence_DelSlice"
  deleteSlice'_ :: ((C2HSImp.Ptr ()) -> (C2HSImp.CLong -> (C2HSImp.CLong -> (IO C2HSImp.CInt))))

foreign import ccall safe "CPython/Protocols/Sequence.chs.h PySequence_Count"
  count'_ :: ((C2HSImp.Ptr ()) -> ((C2HSImp.Ptr ()) -> (IO C2HSImp.CLong)))

foreign import ccall safe "CPython/Protocols/Sequence.chs.h PySequence_Contains"
  contains'_ :: ((C2HSImp.Ptr ()) -> ((C2HSImp.Ptr ()) -> (IO C2HSImp.CInt)))

foreign import ccall safe "CPython/Protocols/Sequence.chs.h PySequence_Index"
  index'_ :: ((C2HSImp.Ptr ()) -> ((C2HSImp.Ptr ()) -> (IO C2HSImp.CLong)))

foreign import ccall safe "CPython/Protocols/Sequence.chs.h PySequence_List"
  toList'_ :: ((C2HSImp.Ptr ()) -> (IO (C2HSImp.Ptr ())))

foreign import ccall safe "CPython/Protocols/Sequence.chs.h PySequence_Tuple"
  toTuple'_ :: ((C2HSImp.Ptr ()) -> (IO (C2HSImp.Ptr ())))

foreign import ccall safe "CPython/Protocols/Sequence.chs.h PySequence_Fast"
  fast'_ :: ((C2HSImp.Ptr ()) -> ((C2HSImp.Ptr C2HSImp.CChar) -> (IO (C2HSImp.Ptr ()))))