cpython-3.1.1.0: CPython/Types/Tuple.chs
-- 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/>.
--
{-# LANGUAGE ForeignFunctionInterface #-}
module CPython.Types.Tuple
( Tuple
, tupleType
, toTuple
, iterableToTuple
, fromTuple
, length
, getItem
, getSlice
, setItem
) where
import Prelude hiding (length)
import CPython.Internal hiding (new)
#include <hscpython-shim.h>
instance Concrete Tuple where
concreteType _ = tupleType
{# fun pure hscpython_PyTuple_Type as tupleType
{} -> `Type' peekStaticObject* #}
toTuple :: [SomeObject] -> IO Tuple
toTuple xs =
mapWith withObject xs $ \ptrs ->
withArrayLen ptrs $ \count array ->
{# call hscpython_poke_tuple #} (fromIntegral count) array
>>= stealObject
-- | Convert any object implementing the iterator protocol to a 'Tuple'.
--
iterableToTuple :: Object iter => iter -> IO Tuple
iterableToTuple iter = do
raw <- callObjectRaw tupleType =<< toTuple [toObject iter]
return $ unsafeCast raw
fromTuple :: Tuple -> IO [SomeObject]
fromTuple py =
withObject py $ \pyPtr ->
({# call PyTuple_Size as ^ #} pyPtr >>=) $ \size ->
let size' = fromIntegral size :: Int in
withArray (replicate size' nullPtr) $ \ptrs ->
{# call hscpython_peek_tuple #} pyPtr size ptrs >>
peekArray size' ptrs >>= mapM peekObject
{# fun PyTuple_Size as length
{ withObject* `Tuple'
} -> `Integer' checkIntReturn* #}
-- | Return the object at a given index from a tuple, or throws @IndexError@
-- if the index is out of bounds.
--
{# fun PyTuple_GetItem as getItem
{ withObject* `Tuple'
, fromIntegral `Integer'
} -> `SomeObject' peekObject* #}
-- | Take a slice of a tuple from /low/ to /high/, and return it as a new
-- tuple.
--
{# fun PyTuple_GetSlice as getSlice
{ withObject* `Tuple'
, fromIntegral `Integer'
, fromIntegral `Integer'
} -> `Tuple' stealObject* #}
setItem :: Object o => Tuple -> Integer -> o -> IO ()
setItem self index x =
withObject self $ \selfPtr ->
withObject x $ \xPtr -> do
incref xPtr
{# call PyTuple_SetItem as ^ #} selfPtr (fromIntegral index) xPtr
>>= checkStatusCode