{- |
Copyright  : Will Thompson, Iñaki García Etxebarria and Jonas Platte
License    : LGPL-2.1
Maintainer : Iñaki García Etxebarria (inaki@blueleaf.cc)

A GstIterator is used to retrieve multiple objects from another object in
a threadsafe way.

Various GStreamer objects provide access to their internal structures using
an iterator.

Note that if calling a GstIterator function results in your code receiving
a refcounted object (with, say, 'GI.GObject.Structs.Value.valueGetObject'), the refcount for that
object will not be increased. Your code is responsible for taking a reference
if it wants to continue using it later.

The basic use pattern of an iterator is as follows:

=== /C code/
>
>  GstIterator *it = _get_iterator(object);
>  GValue item = G_VALUE_INIT;
>  done = FALSE;
>  while (!done) {
>    switch (gst_iterator_next (it, &item)) {
>      case GST_ITERATOR_OK:
>        ...get/use/change item here...
>        g_value_reset (&item);
>        break;
>      case GST_ITERATOR_RESYNC:
>        ...rollback changes to items...
>        gst_iterator_resync (it);
>        break;
>      case GST_ITERATOR_ERROR:
>        ...wrong parameters were given...
>        done = TRUE;
>        break;
>      case GST_ITERATOR_DONE:
>        done = TRUE;
>        break;
>    }
>  }
>  g_value_unset (&item);
>  gst_iterator_free (it);

-}

#define ENABLE_OVERLOADING (MIN_VERSION_haskell_gi_overloading(1,0,0) \
       && !defined(__HADDOCK_VERSION__))

module GI.Gst.Structs.Iterator
    (

-- * Exported types
    Iterator(..)                            ,
    newZeroIterator                         ,
    noIterator                              ,


 -- * Methods
-- ** copy #method:copy#

#if ENABLE_OVERLOADING
    IteratorCopyMethodInfo                  ,
#endif
    iteratorCopy                            ,


-- ** filter #method:filter#

#if ENABLE_OVERLOADING
    IteratorFilterMethodInfo                ,
#endif
    iteratorFilter                          ,


-- ** findCustom #method:findCustom#

#if ENABLE_OVERLOADING
    IteratorFindCustomMethodInfo            ,
#endif
    iteratorFindCustom                      ,


-- ** fold #method:fold#

#if ENABLE_OVERLOADING
    IteratorFoldMethodInfo                  ,
#endif
    iteratorFold                            ,


-- ** foreach #method:foreach#

#if ENABLE_OVERLOADING
    IteratorForeachMethodInfo               ,
#endif
    iteratorForeach                         ,


-- ** free #method:free#

#if ENABLE_OVERLOADING
    IteratorFreeMethodInfo                  ,
#endif
    iteratorFree                            ,


-- ** newSingle #method:newSingle#

    iteratorNewSingle                       ,


-- ** next #method:next#

#if ENABLE_OVERLOADING
    IteratorNextMethodInfo                  ,
#endif
    iteratorNext                            ,


-- ** push #method:push#

#if ENABLE_OVERLOADING
    IteratorPushMethodInfo                  ,
#endif
    iteratorPush                            ,


-- ** resync #method:resync#

#if ENABLE_OVERLOADING
    IteratorResyncMethodInfo                ,
#endif
    iteratorResync                          ,




 -- * Properties
-- ** cookie #attr:cookie#
{- | The cookie; the value of the master_cookie when this iterator was
         created.
-}
    getIteratorCookie                       ,
#if ENABLE_OVERLOADING
    iterator_cookie                         ,
#endif
    setIteratorCookie                       ,


-- ** copy #attr:copy#
{- | The function to copy the iterator
-}
    clearIteratorCopy                       ,
    getIteratorCopy                         ,
#if ENABLE_OVERLOADING
    iterator_copy                           ,
#endif
    setIteratorCopy                         ,


-- ** free #attr:free#
{- | The function to call when the iterator is freed
-}
    clearIteratorFree                       ,
    getIteratorFree                         ,
#if ENABLE_OVERLOADING
    iterator_free                           ,
#endif
    setIteratorFree                         ,


-- ** item #attr:item#
{- | The function to be called for each item retrieved
-}
    clearIteratorItem                       ,
    getIteratorItem                         ,
#if ENABLE_OVERLOADING
    iterator_item                           ,
#endif
    setIteratorItem                         ,


-- ** lock #attr:lock#
{- | The lock protecting the data structure and the cookie.
-}
    clearIteratorLock                       ,
    getIteratorLock                         ,
#if ENABLE_OVERLOADING
    iterator_lock                           ,
#endif
    setIteratorLock                         ,


-- ** masterCookie #attr:masterCookie#
{- | A pointer to the master cookie.
-}
    getIteratorMasterCookie                 ,
#if ENABLE_OVERLOADING
    iterator_masterCookie                   ,
#endif
    setIteratorMasterCookie                 ,


-- ** next #attr:next#
{- | The function to get the next item in the iterator
-}
    clearIteratorNext                       ,
    getIteratorNext                         ,
#if ENABLE_OVERLOADING
    iterator_next                           ,
#endif
    setIteratorNext                         ,


-- ** pushed #attr:pushed#
{- | The iterator that is currently pushed with 'GI.Gst.Structs.Iterator.iteratorPush'
-}
    clearIteratorPushed                     ,
    getIteratorPushed                       ,
#if ENABLE_OVERLOADING
    iterator_pushed                         ,
#endif
    setIteratorPushed                       ,


-- ** resync #attr:resync#
{- | The function to call when a resync is needed.
-}
    clearIteratorResync                     ,
    getIteratorResync                       ,
#if ENABLE_OVERLOADING
    iterator_resync                         ,
#endif
    setIteratorResync                       ,


-- ** size #attr:size#
{- | the size of the iterator
-}
    getIteratorSize                         ,
#if ENABLE_OVERLOADING
    iterator_size                           ,
#endif
    setIteratorSize                         ,


-- ** type #attr:type#
{- | The type of the object that this iterator will return
-}
    getIteratorType                         ,
#if ENABLE_OVERLOADING
    iterator_type                           ,
#endif
    setIteratorType                         ,




    ) where

import Data.GI.Base.ShortPrelude
import qualified Data.GI.Base.ShortPrelude as SP
import qualified Data.GI.Base.Overloading as O
import qualified Prelude as P

import qualified Data.GI.Base.Attributes as GI.Attributes
import qualified Data.GI.Base.ManagedPtr as B.ManagedPtr
import qualified Data.GI.Base.GClosure as B.GClosure
import qualified Data.GI.Base.GError as B.GError
import qualified Data.GI.Base.GVariant as B.GVariant
import qualified Data.GI.Base.GValue as B.GValue
import qualified Data.GI.Base.GParamSpec as B.GParamSpec
import qualified Data.GI.Base.CallStack as B.CallStack
import qualified Data.GI.Base.Properties as B.Properties
import qualified Data.Text as T
import qualified Data.ByteString.Char8 as B
import qualified Data.Map as Map
import qualified Foreign.Ptr as FP
import qualified GHC.OverloadedLabels as OL

import qualified GI.GLib.Callbacks as GLib.Callbacks
import qualified GI.GLib.Unions.Mutex as GLib.Mutex
import qualified GI.Gst.Callbacks as Gst.Callbacks
import {-# SOURCE #-} qualified GI.Gst.Enums as Gst.Enums

-- | Memory-managed wrapper type.
newtype Iterator = Iterator (ManagedPtr Iterator)
foreign import ccall "gst_iterator_get_type" c_gst_iterator_get_type ::
    IO GType

instance BoxedObject Iterator where
    boxedType _ = c_gst_iterator_get_type

-- | Construct a `Iterator` struct initialized to zero.
newZeroIterator :: MonadIO m => m Iterator
newZeroIterator = liftIO $ callocBoxedBytes 120 >>= wrapBoxed Iterator

instance tag ~ 'AttrSet => Constructible Iterator tag where
    new _ attrs = do
        o <- newZeroIterator
        GI.Attributes.set o attrs
        return o


-- | A convenience alias for `Nothing` :: `Maybe` `Iterator`.
noIterator :: Maybe Iterator
noIterator = Nothing

{- |
Get the value of the “@copy@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' iterator #copy
@
-}
getIteratorCopy :: MonadIO m => Iterator -> m (Maybe Gst.Callbacks.IteratorCopyFunction)
getIteratorCopy s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 0) :: IO (FunPtr Gst.Callbacks.C_IteratorCopyFunction)
    result <- SP.convertFunPtrIfNonNull val $ \val' -> do
        let val'' = Gst.Callbacks.dynamic_IteratorCopyFunction val'
        return val''
    return result

{- |
Set the value of the “@copy@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' iterator [ #copy 'Data.GI.Base.Attributes.:=' value ]
@
-}
setIteratorCopy :: MonadIO m => Iterator -> FunPtr Gst.Callbacks.C_IteratorCopyFunction -> m ()
setIteratorCopy s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 0) (val :: FunPtr Gst.Callbacks.C_IteratorCopyFunction)

{- |
Set the value of the “@copy@” field to `Nothing`.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.clear' #copy
@
-}
clearIteratorCopy :: MonadIO m => Iterator -> m ()
clearIteratorCopy s = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 0) (FP.nullFunPtr :: FunPtr Gst.Callbacks.C_IteratorCopyFunction)

#if ENABLE_OVERLOADING
data IteratorCopyFieldInfo
instance AttrInfo IteratorCopyFieldInfo where
    type AttrAllowedOps IteratorCopyFieldInfo = '[ 'AttrSet, 'AttrGet, 'AttrClear]
    type AttrSetTypeConstraint IteratorCopyFieldInfo = (~) (FunPtr Gst.Callbacks.C_IteratorCopyFunction)
    type AttrBaseTypeConstraint IteratorCopyFieldInfo = (~) Iterator
    type AttrGetType IteratorCopyFieldInfo = Maybe Gst.Callbacks.IteratorCopyFunction
    type AttrLabel IteratorCopyFieldInfo = "copy"
    type AttrOrigin IteratorCopyFieldInfo = Iterator
    attrGet _ = getIteratorCopy
    attrSet _ = setIteratorCopy
    attrConstruct = undefined
    attrClear _ = clearIteratorCopy

iterator_copy :: AttrLabelProxy "copy"
iterator_copy = AttrLabelProxy

#endif


{- |
Get the value of the “@next@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' iterator #next
@
-}
getIteratorNext :: MonadIO m => Iterator -> m (Maybe Gst.Callbacks.IteratorNextFunction)
getIteratorNext s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 8) :: IO (FunPtr Gst.Callbacks.C_IteratorNextFunction)
    result <- SP.convertFunPtrIfNonNull val $ \val' -> do
        let val'' = Gst.Callbacks.dynamic_IteratorNextFunction val'
        return val''
    return result

{- |
Set the value of the “@next@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' iterator [ #next 'Data.GI.Base.Attributes.:=' value ]
@
-}
setIteratorNext :: MonadIO m => Iterator -> FunPtr Gst.Callbacks.C_IteratorNextFunction -> m ()
setIteratorNext s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 8) (val :: FunPtr Gst.Callbacks.C_IteratorNextFunction)

{- |
Set the value of the “@next@” field to `Nothing`.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.clear' #next
@
-}
clearIteratorNext :: MonadIO m => Iterator -> m ()
clearIteratorNext s = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 8) (FP.nullFunPtr :: FunPtr Gst.Callbacks.C_IteratorNextFunction)

#if ENABLE_OVERLOADING
data IteratorNextFieldInfo
instance AttrInfo IteratorNextFieldInfo where
    type AttrAllowedOps IteratorNextFieldInfo = '[ 'AttrSet, 'AttrGet, 'AttrClear]
    type AttrSetTypeConstraint IteratorNextFieldInfo = (~) (FunPtr Gst.Callbacks.C_IteratorNextFunction)
    type AttrBaseTypeConstraint IteratorNextFieldInfo = (~) Iterator
    type AttrGetType IteratorNextFieldInfo = Maybe Gst.Callbacks.IteratorNextFunction
    type AttrLabel IteratorNextFieldInfo = "next"
    type AttrOrigin IteratorNextFieldInfo = Iterator
    attrGet _ = getIteratorNext
    attrSet _ = setIteratorNext
    attrConstruct = undefined
    attrClear _ = clearIteratorNext

iterator_next :: AttrLabelProxy "next"
iterator_next = AttrLabelProxy

#endif


{- |
Get the value of the “@item@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' iterator #item
@
-}
getIteratorItem :: MonadIO m => Iterator -> m (Maybe Gst.Callbacks.IteratorItemFunction)
getIteratorItem s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 16) :: IO (FunPtr Gst.Callbacks.C_IteratorItemFunction)
    result <- SP.convertFunPtrIfNonNull val $ \val' -> do
        let val'' = Gst.Callbacks.dynamic_IteratorItemFunction val'
        return val''
    return result

{- |
Set the value of the “@item@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' iterator [ #item 'Data.GI.Base.Attributes.:=' value ]
@
-}
setIteratorItem :: MonadIO m => Iterator -> FunPtr Gst.Callbacks.C_IteratorItemFunction -> m ()
setIteratorItem s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 16) (val :: FunPtr Gst.Callbacks.C_IteratorItemFunction)

{- |
Set the value of the “@item@” field to `Nothing`.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.clear' #item
@
-}
clearIteratorItem :: MonadIO m => Iterator -> m ()
clearIteratorItem s = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 16) (FP.nullFunPtr :: FunPtr Gst.Callbacks.C_IteratorItemFunction)

#if ENABLE_OVERLOADING
data IteratorItemFieldInfo
instance AttrInfo IteratorItemFieldInfo where
    type AttrAllowedOps IteratorItemFieldInfo = '[ 'AttrSet, 'AttrGet, 'AttrClear]
    type AttrSetTypeConstraint IteratorItemFieldInfo = (~) (FunPtr Gst.Callbacks.C_IteratorItemFunction)
    type AttrBaseTypeConstraint IteratorItemFieldInfo = (~) Iterator
    type AttrGetType IteratorItemFieldInfo = Maybe Gst.Callbacks.IteratorItemFunction
    type AttrLabel IteratorItemFieldInfo = "item"
    type AttrOrigin IteratorItemFieldInfo = Iterator
    attrGet _ = getIteratorItem
    attrSet _ = setIteratorItem
    attrConstruct = undefined
    attrClear _ = clearIteratorItem

iterator_item :: AttrLabelProxy "item"
iterator_item = AttrLabelProxy

#endif


{- |
Get the value of the “@resync@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' iterator #resync
@
-}
getIteratorResync :: MonadIO m => Iterator -> m (Maybe Gst.Callbacks.IteratorResyncFunction)
getIteratorResync s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 24) :: IO (FunPtr Gst.Callbacks.C_IteratorResyncFunction)
    result <- SP.convertFunPtrIfNonNull val $ \val' -> do
        let val'' = Gst.Callbacks.dynamic_IteratorResyncFunction val'
        return val''
    return result

{- |
Set the value of the “@resync@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' iterator [ #resync 'Data.GI.Base.Attributes.:=' value ]
@
-}
setIteratorResync :: MonadIO m => Iterator -> FunPtr Gst.Callbacks.C_IteratorResyncFunction -> m ()
setIteratorResync s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 24) (val :: FunPtr Gst.Callbacks.C_IteratorResyncFunction)

{- |
Set the value of the “@resync@” field to `Nothing`.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.clear' #resync
@
-}
clearIteratorResync :: MonadIO m => Iterator -> m ()
clearIteratorResync s = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 24) (FP.nullFunPtr :: FunPtr Gst.Callbacks.C_IteratorResyncFunction)

#if ENABLE_OVERLOADING
data IteratorResyncFieldInfo
instance AttrInfo IteratorResyncFieldInfo where
    type AttrAllowedOps IteratorResyncFieldInfo = '[ 'AttrSet, 'AttrGet, 'AttrClear]
    type AttrSetTypeConstraint IteratorResyncFieldInfo = (~) (FunPtr Gst.Callbacks.C_IteratorResyncFunction)
    type AttrBaseTypeConstraint IteratorResyncFieldInfo = (~) Iterator
    type AttrGetType IteratorResyncFieldInfo = Maybe Gst.Callbacks.IteratorResyncFunction
    type AttrLabel IteratorResyncFieldInfo = "resync"
    type AttrOrigin IteratorResyncFieldInfo = Iterator
    attrGet _ = getIteratorResync
    attrSet _ = setIteratorResync
    attrConstruct = undefined
    attrClear _ = clearIteratorResync

iterator_resync :: AttrLabelProxy "resync"
iterator_resync = AttrLabelProxy

#endif


{- |
Get the value of the “@free@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' iterator #free
@
-}
getIteratorFree :: MonadIO m => Iterator -> m (Maybe Gst.Callbacks.IteratorFreeFunction)
getIteratorFree s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 32) :: IO (FunPtr Gst.Callbacks.C_IteratorFreeFunction)
    result <- SP.convertFunPtrIfNonNull val $ \val' -> do
        let val'' = Gst.Callbacks.dynamic_IteratorFreeFunction val'
        return val''
    return result

{- |
Set the value of the “@free@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' iterator [ #free 'Data.GI.Base.Attributes.:=' value ]
@
-}
setIteratorFree :: MonadIO m => Iterator -> FunPtr Gst.Callbacks.C_IteratorFreeFunction -> m ()
setIteratorFree s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 32) (val :: FunPtr Gst.Callbacks.C_IteratorFreeFunction)

{- |
Set the value of the “@free@” field to `Nothing`.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.clear' #free
@
-}
clearIteratorFree :: MonadIO m => Iterator -> m ()
clearIteratorFree s = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 32) (FP.nullFunPtr :: FunPtr Gst.Callbacks.C_IteratorFreeFunction)

#if ENABLE_OVERLOADING
data IteratorFreeFieldInfo
instance AttrInfo IteratorFreeFieldInfo where
    type AttrAllowedOps IteratorFreeFieldInfo = '[ 'AttrSet, 'AttrGet, 'AttrClear]
    type AttrSetTypeConstraint IteratorFreeFieldInfo = (~) (FunPtr Gst.Callbacks.C_IteratorFreeFunction)
    type AttrBaseTypeConstraint IteratorFreeFieldInfo = (~) Iterator
    type AttrGetType IteratorFreeFieldInfo = Maybe Gst.Callbacks.IteratorFreeFunction
    type AttrLabel IteratorFreeFieldInfo = "free"
    type AttrOrigin IteratorFreeFieldInfo = Iterator
    attrGet _ = getIteratorFree
    attrSet _ = setIteratorFree
    attrConstruct = undefined
    attrClear _ = clearIteratorFree

iterator_free :: AttrLabelProxy "free"
iterator_free = AttrLabelProxy

#endif


{- |
Get the value of the “@pushed@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' iterator #pushed
@
-}
getIteratorPushed :: MonadIO m => Iterator -> m (Maybe Iterator)
getIteratorPushed s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 40) :: IO (Ptr Iterator)
    result <- SP.convertIfNonNull val $ \val' -> do
        val'' <- (newBoxed Iterator) val'
        return val''
    return result

{- |
Set the value of the “@pushed@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' iterator [ #pushed 'Data.GI.Base.Attributes.:=' value ]
@
-}
setIteratorPushed :: MonadIO m => Iterator -> Ptr Iterator -> m ()
setIteratorPushed s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 40) (val :: Ptr Iterator)

{- |
Set the value of the “@pushed@” field to `Nothing`.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.clear' #pushed
@
-}
clearIteratorPushed :: MonadIO m => Iterator -> m ()
clearIteratorPushed s = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 40) (FP.nullPtr :: Ptr Iterator)

#if ENABLE_OVERLOADING
data IteratorPushedFieldInfo
instance AttrInfo IteratorPushedFieldInfo where
    type AttrAllowedOps IteratorPushedFieldInfo = '[ 'AttrSet, 'AttrGet, 'AttrClear]
    type AttrSetTypeConstraint IteratorPushedFieldInfo = (~) (Ptr Iterator)
    type AttrBaseTypeConstraint IteratorPushedFieldInfo = (~) Iterator
    type AttrGetType IteratorPushedFieldInfo = Maybe Iterator
    type AttrLabel IteratorPushedFieldInfo = "pushed"
    type AttrOrigin IteratorPushedFieldInfo = Iterator
    attrGet _ = getIteratorPushed
    attrSet _ = setIteratorPushed
    attrConstruct = undefined
    attrClear _ = clearIteratorPushed

iterator_pushed :: AttrLabelProxy "pushed"
iterator_pushed = AttrLabelProxy

#endif


{- |
Get the value of the “@type@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' iterator #type
@
-}
getIteratorType :: MonadIO m => Iterator -> m GType
getIteratorType s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 48) :: IO CGType
    let val' = GType val
    return val'

{- |
Set the value of the “@type@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' iterator [ #type 'Data.GI.Base.Attributes.:=' value ]
@
-}
setIteratorType :: MonadIO m => Iterator -> GType -> m ()
setIteratorType s val = liftIO $ withManagedPtr s $ \ptr -> do
    let val' = gtypeToCGType val
    poke (ptr `plusPtr` 48) (val' :: CGType)

#if ENABLE_OVERLOADING
data IteratorTypeFieldInfo
instance AttrInfo IteratorTypeFieldInfo where
    type AttrAllowedOps IteratorTypeFieldInfo = '[ 'AttrSet, 'AttrGet]
    type AttrSetTypeConstraint IteratorTypeFieldInfo = (~) GType
    type AttrBaseTypeConstraint IteratorTypeFieldInfo = (~) Iterator
    type AttrGetType IteratorTypeFieldInfo = GType
    type AttrLabel IteratorTypeFieldInfo = "type"
    type AttrOrigin IteratorTypeFieldInfo = Iterator
    attrGet _ = getIteratorType
    attrSet _ = setIteratorType
    attrConstruct = undefined
    attrClear _ = undefined

iterator_type :: AttrLabelProxy "type"
iterator_type = AttrLabelProxy

#endif


{- |
Get the value of the “@lock@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' iterator #lock
@
-}
getIteratorLock :: MonadIO m => Iterator -> m (Maybe GLib.Mutex.Mutex)
getIteratorLock s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 56) :: IO (Ptr GLib.Mutex.Mutex)
    result <- SP.convertIfNonNull val $ \val' -> do
        val'' <- (newPtr GLib.Mutex.Mutex) val'
        return val''
    return result

{- |
Set the value of the “@lock@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' iterator [ #lock 'Data.GI.Base.Attributes.:=' value ]
@
-}
setIteratorLock :: MonadIO m => Iterator -> Ptr GLib.Mutex.Mutex -> m ()
setIteratorLock s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 56) (val :: Ptr GLib.Mutex.Mutex)

{- |
Set the value of the “@lock@” field to `Nothing`.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.clear' #lock
@
-}
clearIteratorLock :: MonadIO m => Iterator -> m ()
clearIteratorLock s = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 56) (FP.nullPtr :: Ptr GLib.Mutex.Mutex)

#if ENABLE_OVERLOADING
data IteratorLockFieldInfo
instance AttrInfo IteratorLockFieldInfo where
    type AttrAllowedOps IteratorLockFieldInfo = '[ 'AttrSet, 'AttrGet, 'AttrClear]
    type AttrSetTypeConstraint IteratorLockFieldInfo = (~) (Ptr GLib.Mutex.Mutex)
    type AttrBaseTypeConstraint IteratorLockFieldInfo = (~) Iterator
    type AttrGetType IteratorLockFieldInfo = Maybe GLib.Mutex.Mutex
    type AttrLabel IteratorLockFieldInfo = "lock"
    type AttrOrigin IteratorLockFieldInfo = Iterator
    attrGet _ = getIteratorLock
    attrSet _ = setIteratorLock
    attrConstruct = undefined
    attrClear _ = clearIteratorLock

iterator_lock :: AttrLabelProxy "lock"
iterator_lock = AttrLabelProxy

#endif


{- |
Get the value of the “@cookie@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' iterator #cookie
@
-}
getIteratorCookie :: MonadIO m => Iterator -> m Word32
getIteratorCookie s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 64) :: IO Word32
    return val

{- |
Set the value of the “@cookie@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' iterator [ #cookie 'Data.GI.Base.Attributes.:=' value ]
@
-}
setIteratorCookie :: MonadIO m => Iterator -> Word32 -> m ()
setIteratorCookie s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 64) (val :: Word32)

#if ENABLE_OVERLOADING
data IteratorCookieFieldInfo
instance AttrInfo IteratorCookieFieldInfo where
    type AttrAllowedOps IteratorCookieFieldInfo = '[ 'AttrSet, 'AttrGet]
    type AttrSetTypeConstraint IteratorCookieFieldInfo = (~) Word32
    type AttrBaseTypeConstraint IteratorCookieFieldInfo = (~) Iterator
    type AttrGetType IteratorCookieFieldInfo = Word32
    type AttrLabel IteratorCookieFieldInfo = "cookie"
    type AttrOrigin IteratorCookieFieldInfo = Iterator
    attrGet _ = getIteratorCookie
    attrSet _ = setIteratorCookie
    attrConstruct = undefined
    attrClear _ = undefined

iterator_cookie :: AttrLabelProxy "cookie"
iterator_cookie = AttrLabelProxy

#endif


{- |
Get the value of the “@master_cookie@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' iterator #masterCookie
@
-}
getIteratorMasterCookie :: MonadIO m => Iterator -> m Word32
getIteratorMasterCookie s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 72) :: IO Word32
    return val

{- |
Set the value of the “@master_cookie@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' iterator [ #masterCookie 'Data.GI.Base.Attributes.:=' value ]
@
-}
setIteratorMasterCookie :: MonadIO m => Iterator -> Word32 -> m ()
setIteratorMasterCookie s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 72) (val :: Word32)

#if ENABLE_OVERLOADING
data IteratorMasterCookieFieldInfo
instance AttrInfo IteratorMasterCookieFieldInfo where
    type AttrAllowedOps IteratorMasterCookieFieldInfo = '[ 'AttrSet, 'AttrGet]
    type AttrSetTypeConstraint IteratorMasterCookieFieldInfo = (~) Word32
    type AttrBaseTypeConstraint IteratorMasterCookieFieldInfo = (~) Iterator
    type AttrGetType IteratorMasterCookieFieldInfo = Word32
    type AttrLabel IteratorMasterCookieFieldInfo = "master_cookie"
    type AttrOrigin IteratorMasterCookieFieldInfo = Iterator
    attrGet _ = getIteratorMasterCookie
    attrSet _ = setIteratorMasterCookie
    attrConstruct = undefined
    attrClear _ = undefined

iterator_masterCookie :: AttrLabelProxy "masterCookie"
iterator_masterCookie = AttrLabelProxy

#endif


{- |
Get the value of the “@size@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' iterator #size
@
-}
getIteratorSize :: MonadIO m => Iterator -> m Word32
getIteratorSize s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 80) :: IO Word32
    return val

{- |
Set the value of the “@size@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' iterator [ #size 'Data.GI.Base.Attributes.:=' value ]
@
-}
setIteratorSize :: MonadIO m => Iterator -> Word32 -> m ()
setIteratorSize s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 80) (val :: Word32)

#if ENABLE_OVERLOADING
data IteratorSizeFieldInfo
instance AttrInfo IteratorSizeFieldInfo where
    type AttrAllowedOps IteratorSizeFieldInfo = '[ 'AttrSet, 'AttrGet]
    type AttrSetTypeConstraint IteratorSizeFieldInfo = (~) Word32
    type AttrBaseTypeConstraint IteratorSizeFieldInfo = (~) Iterator
    type AttrGetType IteratorSizeFieldInfo = Word32
    type AttrLabel IteratorSizeFieldInfo = "size"
    type AttrOrigin IteratorSizeFieldInfo = Iterator
    attrGet _ = getIteratorSize
    attrSet _ = setIteratorSize
    attrConstruct = undefined
    attrClear _ = undefined

iterator_size :: AttrLabelProxy "size"
iterator_size = AttrLabelProxy

#endif



#if ENABLE_OVERLOADING
instance O.HasAttributeList Iterator
type instance O.AttributeList Iterator = IteratorAttributeList
type IteratorAttributeList = ('[ '("copy", IteratorCopyFieldInfo), '("next", IteratorNextFieldInfo), '("item", IteratorItemFieldInfo), '("resync", IteratorResyncFieldInfo), '("free", IteratorFreeFieldInfo), '("pushed", IteratorPushedFieldInfo), '("type", IteratorTypeFieldInfo), '("lock", IteratorLockFieldInfo), '("cookie", IteratorCookieFieldInfo), '("masterCookie", IteratorMasterCookieFieldInfo), '("size", IteratorSizeFieldInfo)] :: [(Symbol, *)])
#endif

-- method Iterator::new_single
-- method type : Constructor
-- Args : [Arg {argCName = "type", argType = TBasicType TGType, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "#GType of the passed object", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "object", argType = TInterface (Name {namespace = "GObject", name = "Value"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "object that this iterator should return", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Gst", name = "Iterator"}))
-- throws : False
-- Skip return : False

foreign import ccall "gst_iterator_new_single" gst_iterator_new_single ::
    CGType ->                               -- type : TBasicType TGType
    Ptr GValue ->                           -- object : TInterface (Name {namespace = "GObject", name = "Value"})
    IO (Ptr Iterator)

{- |
This 'GI.Gst.Structs.Iterator.Iterator' is a convenient iterator for the common
case where a 'GI.Gst.Structs.Iterator.Iterator' needs to be returned but only
a single object has to be considered. This happens often
for the 'GI.Gst.Callbacks.PadIterIntLinkFunction'.
-}
iteratorNewSingle ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    GType
    {- ^ /@type@/: 'GType' of the passed object -}
    -> GValue
    {- ^ /@object@/: object that this iterator should return -}
    -> m Iterator
    {- ^ __Returns:__ the new 'GI.Gst.Structs.Iterator.Iterator' for /@object@/. -}
iteratorNewSingle type_ object = liftIO $ do
    let type_' = gtypeToCGType type_
    object' <- unsafeManagedPtrGetPtr object
    result <- gst_iterator_new_single type_' object'
    checkUnexpectedReturnNULL "iteratorNewSingle" result
    result' <- (wrapBoxed Iterator) result
    touchManagedPtr object
    return result'

#if ENABLE_OVERLOADING
#endif

-- method Iterator::copy
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "it", argType = TInterface (Name {namespace = "Gst", name = "Iterator"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GstIterator", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Gst", name = "Iterator"}))
-- throws : False
-- Skip return : False

foreign import ccall "gst_iterator_copy" gst_iterator_copy ::
    Ptr Iterator ->                         -- it : TInterface (Name {namespace = "Gst", name = "Iterator"})
    IO (Ptr Iterator)

{- |
Copy the iterator and its state.
-}
iteratorCopy ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Iterator
    {- ^ /@it@/: a 'GI.Gst.Structs.Iterator.Iterator' -}
    -> m Iterator
    {- ^ __Returns:__ a new copy of /@it@/. -}
iteratorCopy it = liftIO $ do
    it' <- unsafeManagedPtrGetPtr it
    result <- gst_iterator_copy it'
    checkUnexpectedReturnNULL "iteratorCopy" result
    result' <- (wrapBoxed Iterator) result
    touchManagedPtr it
    return result'

#if ENABLE_OVERLOADING
data IteratorCopyMethodInfo
instance (signature ~ (m Iterator), MonadIO m) => O.MethodInfo IteratorCopyMethodInfo Iterator signature where
    overloadedMethod _ = iteratorCopy

#endif

-- method Iterator::filter
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "it", argType = TInterface (Name {namespace = "Gst", name = "Iterator"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "The #GstIterator to filter", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "func", argType = TInterface (Name {namespace = "GLib", name = "CompareFunc"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the compare function to select elements", sinceVersion = Nothing}, argScope = ScopeTypeCall, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "user_data", argType = TInterface (Name {namespace = "GObject", name = "Value"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "user data passed to the compare function", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Gst", name = "Iterator"}))
-- throws : False
-- Skip return : False

foreign import ccall "gst_iterator_filter" gst_iterator_filter ::
    Ptr Iterator ->                         -- it : TInterface (Name {namespace = "Gst", name = "Iterator"})
    FunPtr GLib.Callbacks.C_CompareFunc ->  -- func : TInterface (Name {namespace = "GLib", name = "CompareFunc"})
    Ptr GValue ->                           -- user_data : TInterface (Name {namespace = "GObject", name = "Value"})
    IO (Ptr Iterator)

{- |
Create a new iterator from an existing iterator. The new iterator
will only return those elements that match the given compare function /@func@/.
The first parameter that is passed to /@func@/ is the 'GI.GObject.Structs.Value.Value' of the current
iterator element and the second parameter is /@userData@/. /@func@/ should
return 0 for elements that should be included in the filtered iterator.

When this iterator is freed, /@it@/ will also be freed.
-}
iteratorFilter ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Iterator
    {- ^ /@it@/: The 'GI.Gst.Structs.Iterator.Iterator' to filter -}
    -> GLib.Callbacks.CompareFunc
    {- ^ /@func@/: the compare function to select elements -}
    -> GValue
    {- ^ /@userData@/: user data passed to the compare function -}
    -> m Iterator
    {- ^ __Returns:__ a new 'GI.Gst.Structs.Iterator.Iterator'.

MT safe. -}
iteratorFilter it func userData = liftIO $ do
    it' <- unsafeManagedPtrGetPtr it
    func' <- GLib.Callbacks.mk_CompareFunc (GLib.Callbacks.wrap_CompareFunc Nothing func)
    userData' <- unsafeManagedPtrGetPtr userData
    result <- gst_iterator_filter it' func' userData'
    checkUnexpectedReturnNULL "iteratorFilter" result
    result' <- (wrapBoxed Iterator) result
    safeFreeFunPtr $ castFunPtrToPtr func'
    touchManagedPtr it
    touchManagedPtr userData
    return result'

#if ENABLE_OVERLOADING
data IteratorFilterMethodInfo
instance (signature ~ (GLib.Callbacks.CompareFunc -> GValue -> m Iterator), MonadIO m) => O.MethodInfo IteratorFilterMethodInfo Iterator signature where
    overloadedMethod _ = iteratorFilter

#endif

-- method Iterator::find_custom
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "it", argType = TInterface (Name {namespace = "Gst", name = "Iterator"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "The #GstIterator to iterate", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "func", argType = TInterface (Name {namespace = "GLib", name = "CompareFunc"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the compare function to use", sinceVersion = Nothing}, argScope = ScopeTypeCall, argClosure = 3, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "elem", argType = TInterface (Name {namespace = "GObject", name = "Value"}), direction = DirectionOut, mayBeNull = False, argDoc = Documentation {rawDocText = Just "pointer to a #GValue where to store the result", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = True, transfer = TransferNothing},Arg {argCName = "user_data", argType = TBasicType TPtr, direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "user data passed to the compare function", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TBasicType TBoolean)
-- throws : False
-- Skip return : False

foreign import ccall "gst_iterator_find_custom" gst_iterator_find_custom ::
    Ptr Iterator ->                         -- it : TInterface (Name {namespace = "Gst", name = "Iterator"})
    FunPtr GLib.Callbacks.C_CompareFunc ->  -- func : TInterface (Name {namespace = "GLib", name = "CompareFunc"})
    Ptr GValue ->                           -- elem : TInterface (Name {namespace = "GObject", name = "Value"})
    Ptr () ->                               -- user_data : TBasicType TPtr
    IO CInt

{- |
Find the first element in /@it@/ that matches the compare function /@func@/.
/@func@/ should return 0 when the element is found. The first parameter
to /@func@/ will be the current element of the iterator and the
second parameter will be /@userData@/.
The result will be stored in /@elem@/ if a result is found.

The iterator will not be freed.

This function will return 'False' if an error happened to the iterator
or if the element wasn\'t found.
-}
iteratorFindCustom ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Iterator
    {- ^ /@it@/: The 'GI.Gst.Structs.Iterator.Iterator' to iterate -}
    -> GLib.Callbacks.CompareFunc
    {- ^ /@func@/: the compare function to use -}
    -> m ((Bool, GValue))
    {- ^ __Returns:__ Returns 'True' if the element was found, else 'False'.

MT safe. -}
iteratorFindCustom it func = liftIO $ do
    it' <- unsafeManagedPtrGetPtr it
    func' <- GLib.Callbacks.mk_CompareFunc (GLib.Callbacks.wrap_CompareFunc Nothing func)
    elem <- callocBoxedBytes 24 :: IO (Ptr GValue)
    let userData = nullPtr
    result <- gst_iterator_find_custom it' func' elem userData
    let result' = (/= 0) result
    elem' <- (wrapBoxed GValue) elem
    safeFreeFunPtr $ castFunPtrToPtr func'
    touchManagedPtr it
    return (result', elem')

#if ENABLE_OVERLOADING
data IteratorFindCustomMethodInfo
instance (signature ~ (GLib.Callbacks.CompareFunc -> m ((Bool, GValue))), MonadIO m) => O.MethodInfo IteratorFindCustomMethodInfo Iterator signature where
    overloadedMethod _ = iteratorFindCustom

#endif

-- method Iterator::fold
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "it", argType = TInterface (Name {namespace = "Gst", name = "Iterator"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "The #GstIterator to fold over", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "func", argType = TInterface (Name {namespace = "Gst", name = "IteratorFoldFunction"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the fold function", sinceVersion = Nothing}, argScope = ScopeTypeCall, argClosure = 3, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "ret", argType = TInterface (Name {namespace = "GObject", name = "Value"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the seed value passed to the fold function", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "user_data", argType = TBasicType TPtr, direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "user data passed to the fold function", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Gst", name = "IteratorResult"}))
-- throws : False
-- Skip return : False

foreign import ccall "gst_iterator_fold" gst_iterator_fold ::
    Ptr Iterator ->                         -- it : TInterface (Name {namespace = "Gst", name = "Iterator"})
    FunPtr Gst.Callbacks.C_IteratorFoldFunction -> -- func : TInterface (Name {namespace = "Gst", name = "IteratorFoldFunction"})
    Ptr GValue ->                           -- ret : TInterface (Name {namespace = "GObject", name = "Value"})
    Ptr () ->                               -- user_data : TBasicType TPtr
    IO CUInt

{- |
Folds /@func@/ over the elements of /@iter@/. That is to say, /@func@/ will be called
as /@func@/ (object, /@ret@/, /@userData@/) for each object in /@it@/. The normal use
of this procedure is to accumulate the results of operating on the objects in
/@ret@/.

This procedure can be used (and is used internally) to implement the
'GI.Gst.Structs.Iterator.iteratorForeach' and 'GI.Gst.Structs.Iterator.iteratorFindCustom' operations.

The fold will proceed as long as /@func@/ returns 'True'. When the iterator has no
more arguments, 'GI.Gst.Enums.IteratorResultDone' will be returned. If /@func@/ returns 'False',
the fold will stop, and 'GI.Gst.Enums.IteratorResultOk' will be returned. Errors or resyncs
will cause fold to return 'GI.Gst.Enums.IteratorResultError' or 'GI.Gst.Enums.IteratorResultResync' as
appropriate.

The iterator will not be freed.
-}
iteratorFold ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Iterator
    {- ^ /@it@/: The 'GI.Gst.Structs.Iterator.Iterator' to fold over -}
    -> Gst.Callbacks.IteratorFoldFunction
    {- ^ /@func@/: the fold function -}
    -> GValue
    {- ^ /@ret@/: the seed value passed to the fold function -}
    -> m Gst.Enums.IteratorResult
    {- ^ __Returns:__ A 'GI.Gst.Enums.IteratorResult', as described above.

MT safe. -}
iteratorFold it func ret = liftIO $ do
    it' <- unsafeManagedPtrGetPtr it
    func' <- Gst.Callbacks.mk_IteratorFoldFunction (Gst.Callbacks.wrap_IteratorFoldFunction Nothing (Gst.Callbacks.drop_closures_IteratorFoldFunction func))
    ret' <- unsafeManagedPtrGetPtr ret
    let userData = nullPtr
    result <- gst_iterator_fold it' func' ret' userData
    let result' = (toEnum . fromIntegral) result
    safeFreeFunPtr $ castFunPtrToPtr func'
    touchManagedPtr it
    touchManagedPtr ret
    return result'

#if ENABLE_OVERLOADING
data IteratorFoldMethodInfo
instance (signature ~ (Gst.Callbacks.IteratorFoldFunction -> GValue -> m Gst.Enums.IteratorResult), MonadIO m) => O.MethodInfo IteratorFoldMethodInfo Iterator signature where
    overloadedMethod _ = iteratorFold

#endif

-- method Iterator::foreach
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "it", argType = TInterface (Name {namespace = "Gst", name = "Iterator"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "The #GstIterator to iterate", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "func", argType = TInterface (Name {namespace = "Gst", name = "IteratorForeachFunction"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the function to call for each element.", sinceVersion = Nothing}, argScope = ScopeTypeCall, argClosure = 2, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "user_data", argType = TBasicType TPtr, direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "user data passed to the function", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Gst", name = "IteratorResult"}))
-- throws : False
-- Skip return : False

foreign import ccall "gst_iterator_foreach" gst_iterator_foreach ::
    Ptr Iterator ->                         -- it : TInterface (Name {namespace = "Gst", name = "Iterator"})
    FunPtr Gst.Callbacks.C_IteratorForeachFunction -> -- func : TInterface (Name {namespace = "Gst", name = "IteratorForeachFunction"})
    Ptr () ->                               -- user_data : TBasicType TPtr
    IO CUInt

{- |
Iterate over all element of /@it@/ and call the given function /@func@/ for
each element.
-}
iteratorForeach ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Iterator
    {- ^ /@it@/: The 'GI.Gst.Structs.Iterator.Iterator' to iterate -}
    -> Gst.Callbacks.IteratorForeachFunction
    {- ^ /@func@/: the function to call for each element. -}
    -> m Gst.Enums.IteratorResult
    {- ^ __Returns:__ the result call to 'GI.Gst.Structs.Iterator.iteratorFold'. The iterator will not be
freed.

MT safe. -}
iteratorForeach it func = liftIO $ do
    it' <- unsafeManagedPtrGetPtr it
    func' <- Gst.Callbacks.mk_IteratorForeachFunction (Gst.Callbacks.wrap_IteratorForeachFunction Nothing (Gst.Callbacks.drop_closures_IteratorForeachFunction func))
    let userData = nullPtr
    result <- gst_iterator_foreach it' func' userData
    let result' = (toEnum . fromIntegral) result
    safeFreeFunPtr $ castFunPtrToPtr func'
    touchManagedPtr it
    return result'

#if ENABLE_OVERLOADING
data IteratorForeachMethodInfo
instance (signature ~ (Gst.Callbacks.IteratorForeachFunction -> m Gst.Enums.IteratorResult), MonadIO m) => O.MethodInfo IteratorForeachMethodInfo Iterator signature where
    overloadedMethod _ = iteratorForeach

#endif

-- method Iterator::free
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "it", argType = TInterface (Name {namespace = "Gst", name = "Iterator"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "The #GstIterator to free", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "gst_iterator_free" gst_iterator_free ::
    Ptr Iterator ->                         -- it : TInterface (Name {namespace = "Gst", name = "Iterator"})
    IO ()

{- |
Free the iterator.

MT safe.
-}
iteratorFree ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Iterator
    {- ^ /@it@/: The 'GI.Gst.Structs.Iterator.Iterator' to free -}
    -> m ()
iteratorFree it = liftIO $ do
    it' <- unsafeManagedPtrGetPtr it
    gst_iterator_free it'
    touchManagedPtr it
    return ()

#if ENABLE_OVERLOADING
data IteratorFreeMethodInfo
instance (signature ~ (m ()), MonadIO m) => O.MethodInfo IteratorFreeMethodInfo Iterator signature where
    overloadedMethod _ = iteratorFree

#endif

-- method Iterator::next
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "it", argType = TInterface (Name {namespace = "Gst", name = "Iterator"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "The #GstIterator to iterate", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "elem", argType = TInterface (Name {namespace = "GObject", name = "Value"}), direction = DirectionOut, mayBeNull = False, argDoc = Documentation {rawDocText = Just "pointer to hold next element", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = True, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Gst", name = "IteratorResult"}))
-- throws : False
-- Skip return : False

foreign import ccall "gst_iterator_next" gst_iterator_next ::
    Ptr Iterator ->                         -- it : TInterface (Name {namespace = "Gst", name = "Iterator"})
    Ptr GValue ->                           -- elem : TInterface (Name {namespace = "GObject", name = "Value"})
    IO CUInt

{- |
Get the next item from the iterator in /@elem@/.

Only when this function returns 'GI.Gst.Enums.IteratorResultOk', /@elem@/ will contain a valid
value. /@elem@/ must have been initialized to the type of the iterator or
initialized to zeroes with 'GI.GObject.Structs.Value.valueUnset'. The caller is responsible for
unsetting or resetting /@elem@/ with 'GI.GObject.Structs.Value.valueUnset' or 'GI.GObject.Structs.Value.valueReset'
after usage.

When this function returns 'GI.Gst.Enums.IteratorResultDone', no more elements can be
retrieved from /@it@/.

A return value of 'GI.Gst.Enums.IteratorResultResync' indicates that the element list was
concurrently updated. The user of /@it@/ should call 'GI.Gst.Structs.Iterator.iteratorResync' to
get the newly updated list.

A return value of 'GI.Gst.Enums.IteratorResultError' indicates an unrecoverable fatal error.
-}
iteratorNext ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Iterator
    {- ^ /@it@/: The 'GI.Gst.Structs.Iterator.Iterator' to iterate -}
    -> m ((Gst.Enums.IteratorResult, GValue))
    {- ^ __Returns:__ The result of the iteration. Unset /@elem@/ after usage.

MT safe. -}
iteratorNext it = liftIO $ do
    it' <- unsafeManagedPtrGetPtr it
    elem <- callocBoxedBytes 24 :: IO (Ptr GValue)
    result <- gst_iterator_next it' elem
    let result' = (toEnum . fromIntegral) result
    elem' <- (wrapBoxed GValue) elem
    touchManagedPtr it
    return (result', elem')

#if ENABLE_OVERLOADING
data IteratorNextMethodInfo
instance (signature ~ (m ((Gst.Enums.IteratorResult, GValue))), MonadIO m) => O.MethodInfo IteratorNextMethodInfo Iterator signature where
    overloadedMethod _ = iteratorNext

#endif

-- method Iterator::push
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "it", argType = TInterface (Name {namespace = "Gst", name = "Iterator"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "The #GstIterator to use", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "other", argType = TInterface (Name {namespace = "Gst", name = "Iterator"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "The #GstIterator to push", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "gst_iterator_push" gst_iterator_push ::
    Ptr Iterator ->                         -- it : TInterface (Name {namespace = "Gst", name = "Iterator"})
    Ptr Iterator ->                         -- other : TInterface (Name {namespace = "Gst", name = "Iterator"})
    IO ()

{- |
Pushes /@other@/ iterator onto /@it@/. All calls performed on /@it@/ are
forwarded to /@other@/. If /@other@/ returns 'GI.Gst.Enums.IteratorResultDone', it is
popped again and calls are handled by /@it@/ again.

This function is mainly used by objects implementing the iterator
next function to recurse into substructures.

When 'GI.Gst.Structs.Iterator.iteratorResync' is called on /@it@/, /@other@/ will automatically be
popped.

MT safe.
-}
iteratorPush ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Iterator
    {- ^ /@it@/: The 'GI.Gst.Structs.Iterator.Iterator' to use -}
    -> Iterator
    {- ^ /@other@/: The 'GI.Gst.Structs.Iterator.Iterator' to push -}
    -> m ()
iteratorPush it other = liftIO $ do
    it' <- unsafeManagedPtrGetPtr it
    other' <- unsafeManagedPtrGetPtr other
    gst_iterator_push it' other'
    touchManagedPtr it
    touchManagedPtr other
    return ()

#if ENABLE_OVERLOADING
data IteratorPushMethodInfo
instance (signature ~ (Iterator -> m ()), MonadIO m) => O.MethodInfo IteratorPushMethodInfo Iterator signature where
    overloadedMethod _ = iteratorPush

#endif

-- method Iterator::resync
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "it", argType = TInterface (Name {namespace = "Gst", name = "Iterator"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "The #GstIterator to resync", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "gst_iterator_resync" gst_iterator_resync ::
    Ptr Iterator ->                         -- it : TInterface (Name {namespace = "Gst", name = "Iterator"})
    IO ()

{- |
Resync the iterator. this function is mostly called
after 'GI.Gst.Structs.Iterator.iteratorNext' returned 'GI.Gst.Enums.IteratorResultResync'.

When an iterator was pushed on /@it@/, it will automatically be popped again
with this function.

MT safe.
-}
iteratorResync ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Iterator
    {- ^ /@it@/: The 'GI.Gst.Structs.Iterator.Iterator' to resync -}
    -> m ()
iteratorResync it = liftIO $ do
    it' <- unsafeManagedPtrGetPtr it
    gst_iterator_resync it'
    touchManagedPtr it
    return ()

#if ENABLE_OVERLOADING
data IteratorResyncMethodInfo
instance (signature ~ (m ()), MonadIO m) => O.MethodInfo IteratorResyncMethodInfo Iterator signature where
    overloadedMethod _ = iteratorResync

#endif

#if ENABLE_OVERLOADING
type family ResolveIteratorMethod (t :: Symbol) (o :: *) :: * where
    ResolveIteratorMethod "copy" o = IteratorCopyMethodInfo
    ResolveIteratorMethod "filter" o = IteratorFilterMethodInfo
    ResolveIteratorMethod "findCustom" o = IteratorFindCustomMethodInfo
    ResolveIteratorMethod "fold" o = IteratorFoldMethodInfo
    ResolveIteratorMethod "foreach" o = IteratorForeachMethodInfo
    ResolveIteratorMethod "free" o = IteratorFreeMethodInfo
    ResolveIteratorMethod "next" o = IteratorNextMethodInfo
    ResolveIteratorMethod "push" o = IteratorPushMethodInfo
    ResolveIteratorMethod "resync" o = IteratorResyncMethodInfo
    ResolveIteratorMethod l o = O.MethodResolutionFailed l o

instance (info ~ ResolveIteratorMethod t Iterator, O.MethodInfo info Iterator p) => OL.IsLabel t (Iterator -> p) where
#if MIN_VERSION_base(4,10,0)
    fromLabel = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)
#else
    fromLabel _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)
#endif

#endif