{-# LANGUAGE TypeApplications #-}


-- | Copyright  : Will Thompson and Iñaki García Etxebarria
-- License    : LGPL-2.1
-- Maintainer : Iñaki García Etxebarria
-- 
-- A generic iterator API

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

module GI.Wp.Structs.Iterator
    ( 

-- * Exported types
    Iterator(..)                            ,


 -- * Methods
-- | 
-- 
--  === __Click to display all available methods, including inherited ones__
-- ==== Methods
-- [foreach]("GI.Wp.Structs.Iterator#g:method:foreach"), [next]("GI.Wp.Structs.Iterator#g:method:next"), [ref]("GI.Wp.Structs.Iterator#g:method:ref"), [reset]("GI.Wp.Structs.Iterator#g:method:reset"), [unref]("GI.Wp.Structs.Iterator#g:method:unref").
-- 
-- ==== Getters
-- [getUserData]("GI.Wp.Structs.Iterator#g:method:getUserData").
-- 
-- ==== Setters
-- /None/.

#if defined(ENABLE_OVERLOADING)
    ResolveIteratorMethod                   ,
#endif

-- ** foreach #method:foreach#

#if defined(ENABLE_OVERLOADING)
    IteratorForeachMethodInfo               ,
#endif
    iteratorForeach                         ,


-- ** getUserData #method:getUserData#

#if defined(ENABLE_OVERLOADING)
    IteratorGetUserDataMethodInfo           ,
#endif
    iteratorGetUserData                     ,


-- ** new #method:new#

    iteratorNew                             ,


-- ** next #method:next#

#if defined(ENABLE_OVERLOADING)
    IteratorNextMethodInfo                  ,
#endif
    iteratorNext                            ,


-- ** ref #method:ref#

#if defined(ENABLE_OVERLOADING)
    IteratorRefMethodInfo                   ,
#endif
    iteratorRef                             ,


-- ** reset #method:reset#

#if defined(ENABLE_OVERLOADING)
    IteratorResetMethodInfo                 ,
#endif
    iteratorReset                           ,


-- ** unref #method:unref#

#if defined(ENABLE_OVERLOADING)
    IteratorUnrefMethodInfo                 ,
#endif
    iteratorUnref                           ,




    ) 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.BasicTypes as B.Types
import qualified Data.GI.Base.ManagedPtr as B.ManagedPtr
import qualified Data.GI.Base.GArray as B.GArray
import qualified Data.GI.Base.GClosure as B.GClosure
import qualified Data.GI.Base.GError as B.GError
import qualified Data.GI.Base.GHashTable as B.GHT
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.GI.Base.Signals as B.Signals
import qualified Control.Monad.IO.Class as MIO
import qualified Data.Coerce as Coerce
import qualified Data.Text as T
import qualified Data.Kind as DK
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 GHC.Records as R
import qualified Data.Word as DW
import qualified Data.Int as DI
import qualified System.Posix.Types as SPT
import qualified Foreign.C.Types as FCT

-- Workaround for https://gitlab.haskell.org/ghc/ghc/-/issues/23392
#if MIN_VERSION_base(4,18,0)
import qualified GI.Wp.Callbacks as Wp.Callbacks
import {-# SOURCE #-} qualified GI.Wp.Structs.IteratorMethods as Wp.IteratorMethods

#else
import qualified GI.Wp.Callbacks as Wp.Callbacks
import {-# SOURCE #-} qualified GI.Wp.Structs.IteratorMethods as Wp.IteratorMethods

#endif

-- | Memory-managed wrapper type.
newtype Iterator = Iterator (SP.ManagedPtr Iterator)
    deriving (Eq)

instance SP.ManagedPtrNewtype Iterator where
    toManagedPtr (Iterator p) = p

foreign import ccall "wp_iterator_get_type" c_wp_iterator_get_type :: 
    IO GType

type instance O.ParentTypes Iterator = '[]
instance O.HasParentTypes Iterator

instance B.Types.TypedObject Iterator where
    glibType = c_wp_iterator_get_type

instance B.Types.GBoxed Iterator

-- | Convert t'Iterator' to and from 'Data.GI.Base.GValue.GValue'. See 'Data.GI.Base.GValue.toGValue' and 'Data.GI.Base.GValue.fromGValue'.
instance B.GValue.IsGValue (Maybe Iterator) where
    gvalueGType_ = c_wp_iterator_get_type
    gvalueSet_ gv P.Nothing = B.GValue.set_boxed gv (FP.nullPtr :: FP.Ptr Iterator)
    gvalueSet_ gv (P.Just obj) = B.ManagedPtr.withManagedPtr obj (B.GValue.set_boxed gv)
    gvalueGet_ gv = do
        ptr <- B.GValue.get_boxed gv :: IO (Ptr Iterator)
        if ptr /= FP.nullPtr
        then P.Just <$> B.ManagedPtr.newBoxed Iterator ptr
        else return P.Nothing
        
    


#if defined(ENABLE_OVERLOADING)
instance O.HasAttributeList Iterator
type instance O.AttributeList Iterator = IteratorAttributeList
type IteratorAttributeList = ('[ ] :: [(Symbol, DK.Type)])
#endif

-- method Iterator::new
-- method type : Constructor
-- Args: [ Arg
--           { argCName = "methods"
--           , argType =
--               TInterface Name { namespace = "Wp" , name = "IteratorMethods" }
--           , argCType = Just "const WpIteratorMethods*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "method implementations for the new iterator"
--                 , sinceVersion = Nothing
--                 }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       , Arg
--           { argCName = "user_size"
--           , argType = TBasicType TSize
--           , argCType = Just "size_t"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText =
--                     Just "size of the user_data structure to be allocated"
--                 , sinceVersion = Nothing
--                 }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       ]
-- Lengths: []
-- returnType: Just (TInterface Name { namespace = "Wp" , name = "Iterator" })
-- throws : False
-- Skip return : False

foreign import ccall "wp_iterator_new" wp_iterator_new :: 
    Ptr Wp.IteratorMethods.IteratorMethods -> -- methods : TInterface (Name {namespace = "Wp", name = "IteratorMethods"})
    FCT.CSize ->                            -- user_size : TBasicType TSize
    IO (Ptr Iterator)

-- | Constructs an iterator that uses the provided /@methods@/ to implement its API.
-- 
-- 
-- The WpIterator structure is internally allocated with /@userSize@/ additional space at the end. A pointer to this space can be retrieved with 'GI.Wp.Structs.Iterator.iteratorGetUserData' and is available for implementation-specific storage.
iteratorNew ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Wp.IteratorMethods.IteratorMethods
    -- ^ /@methods@/: method implementations for the new iterator
    -> FCT.CSize
    -- ^ /@userSize@/: size of the user_data structure to be allocated
    -> m Iterator
    -- ^ __Returns:__ a new custom iterator
iteratorNew methods userSize = liftIO $ do
    methods' <- unsafeManagedPtrGetPtr methods
    result <- wp_iterator_new methods' userSize
    checkUnexpectedReturnNULL "iteratorNew" result
    result' <- (wrapBoxed Iterator) result
    touchManagedPtr methods
    return result'

#if defined(ENABLE_OVERLOADING)
#endif

-- XXX Could not generate method Iterator::fold
-- Bad introspection data: C type for argument ‘ret’ is not a pointer to a pointer
-- method Iterator::foreach
-- method type : OrdinaryMethod
-- Args: [ Arg
--           { argCName = "self"
--           , argType =
--               TInterface Name { namespace = "Wp" , name = "Iterator" }
--           , argCType = Just "WpIterator*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "the iterator" , sinceVersion = Nothing }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       , Arg
--           { argCName = "func"
--           , argType =
--               TInterface Name { namespace = "Wp" , name = "IteratorForeachFunc" }
--           , argCType = Just "WpIteratorForeachFunc"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "the foreach function"
--                 , sinceVersion = Nothing
--                 }
--           , argScope = ScopeTypeCall
--           , argClosure = 2
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       , Arg
--           { argCName = "data"
--           , argType = TBasicType TPtr
--           , argCType = Just "gpointer"
--           , direction = DirectionIn
--           , mayBeNull = True
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "the user data" , sinceVersion = Nothing }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       ]
-- Lengths: []
-- returnType: Just (TBasicType TBoolean)
-- throws : False
-- Skip return : False

foreign import ccall "wp_iterator_foreach" wp_iterator_foreach :: 
    Ptr Iterator ->                         -- self : TInterface (Name {namespace = "Wp", name = "Iterator"})
    FunPtr Wp.Callbacks.C_IteratorForeachFunc -> -- func : TInterface (Name {namespace = "Wp", name = "IteratorForeachFunc"})
    Ptr () ->                               -- data : TBasicType TPtr
    IO CInt

-- | Iterates over all items of the iterator calling a function.
iteratorForeach ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Iterator
    -- ^ /@self@/: the iterator
    -> Wp.Callbacks.IteratorForeachFunc
    -- ^ /@func@/: the foreach function
    -> m Bool
    -- ^ __Returns:__ TRUE if all the items were processed, FALSE otherwise.
iteratorForeach self func = liftIO $ do
    self' <- unsafeManagedPtrGetPtr self
    func' <- Wp.Callbacks.mk_IteratorForeachFunc (Wp.Callbacks.wrap_IteratorForeachFunc Nothing func)
    let data_ = nullPtr
    result <- wp_iterator_foreach self' func' data_
    let result' = (/= 0) result
    safeFreeFunPtr $ castFunPtrToPtr func'
    touchManagedPtr self
    return result'

#if defined(ENABLE_OVERLOADING)
data IteratorForeachMethodInfo
instance (signature ~ (Wp.Callbacks.IteratorForeachFunc -> m Bool), MonadIO m) => O.OverloadedMethod IteratorForeachMethodInfo Iterator signature where
    overloadedMethod = iteratorForeach

instance O.OverloadedMethodInfo IteratorForeachMethodInfo Iterator where
    overloadedMethodInfo = P.Just (O.ResolvedSymbolInfo {
        O.resolvedSymbolName = "GI.Wp.Structs.Iterator.iteratorForeach",
        O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-wireplumber-0.5.14.2/docs/GI-Wp-Structs-Iterator.html#v:iteratorForeach"
        })


#endif

-- method Iterator::get_user_data
-- method type : OrdinaryMethod
-- Args: [ Arg
--           { argCName = "self"
--           , argType =
--               TInterface Name { namespace = "Wp" , name = "Iterator" }
--           , argCType = Just "WpIterator*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "an iterator object" , sinceVersion = Nothing }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       ]
-- Lengths: []
-- returnType: Just (TBasicType TPtr)
-- throws : False
-- Skip return : False

foreign import ccall "wp_iterator_get_user_data" wp_iterator_get_user_data :: 
    Ptr Iterator ->                         -- self : TInterface (Name {namespace = "Wp", name = "Iterator"})
    IO (Ptr ())

-- | Gets the implementation-specific storage of an iterator.
-- 
-- 
-- this only for use by implementations of WpIterator
iteratorGetUserData ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Iterator
    -- ^ /@self@/: an iterator object
    -> m (Ptr ())
    -- ^ __Returns:__ a pointer to the implementation-specific storage area
iteratorGetUserData self = liftIO $ do
    self' <- unsafeManagedPtrGetPtr self
    result <- wp_iterator_get_user_data self'
    touchManagedPtr self
    return result

#if defined(ENABLE_OVERLOADING)
data IteratorGetUserDataMethodInfo
instance (signature ~ (m (Ptr ())), MonadIO m) => O.OverloadedMethod IteratorGetUserDataMethodInfo Iterator signature where
    overloadedMethod = iteratorGetUserData

instance O.OverloadedMethodInfo IteratorGetUserDataMethodInfo Iterator where
    overloadedMethodInfo = P.Just (O.ResolvedSymbolInfo {
        O.resolvedSymbolName = "GI.Wp.Structs.Iterator.iteratorGetUserData",
        O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-wireplumber-0.5.14.2/docs/GI-Wp-Structs-Iterator.html#v:iteratorGetUserData"
        })


#endif

-- method Iterator::next
-- method type : OrdinaryMethod
-- Args: [ Arg
--           { argCName = "self"
--           , argType =
--               TInterface Name { namespace = "Wp" , name = "Iterator" }
--           , argCType = Just "WpIterator*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "the iterator" , sinceVersion = Nothing }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       , Arg
--           { argCName = "item"
--           , argType = TGValue
--           , argCType = Just "GValue*"
--           , direction = DirectionOut
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "the next item of the iterator"
--                 , sinceVersion = Nothing
--                 }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = True
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       ]
-- Lengths: []
-- returnType: Just (TBasicType TBoolean)
-- throws : False
-- Skip return : False

foreign import ccall "wp_iterator_next" wp_iterator_next :: 
    Ptr Iterator ->                         -- self : TInterface (Name {namespace = "Wp", name = "Iterator"})
    Ptr GValue ->                           -- item : TGValue
    IO CInt

-- | Gets the next item of the iterator.
iteratorNext ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Iterator
    -- ^ /@self@/: the iterator
    -> m ((Bool, GValue))
    -- ^ __Returns:__ TRUE if next iterator was obtained, FALSE when the iterator has no more items to iterate through.
iteratorNext self = liftIO $ do
    self' <- unsafeManagedPtrGetPtr self
    item <- SP.callocBytes 24 :: IO (Ptr GValue)
    result <- wp_iterator_next self' item
    let result' = (/= 0) result
    item' <- B.GValue.wrapGValuePtr item
    touchManagedPtr self
    return (result', item')

#if defined(ENABLE_OVERLOADING)
data IteratorNextMethodInfo
instance (signature ~ (m ((Bool, GValue))), MonadIO m) => O.OverloadedMethod IteratorNextMethodInfo Iterator signature where
    overloadedMethod = iteratorNext

instance O.OverloadedMethodInfo IteratorNextMethodInfo Iterator where
    overloadedMethodInfo = P.Just (O.ResolvedSymbolInfo {
        O.resolvedSymbolName = "GI.Wp.Structs.Iterator.iteratorNext",
        O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-wireplumber-0.5.14.2/docs/GI-Wp-Structs-Iterator.html#v:iteratorNext"
        })


#endif

-- method Iterator::ref
-- method type : OrdinaryMethod
-- Args: [ Arg
--           { argCName = "self"
--           , argType =
--               TInterface Name { namespace = "Wp" , name = "Iterator" }
--           , argCType = Just "WpIterator*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "an iterator object" , sinceVersion = Nothing }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       ]
-- Lengths: []
-- returnType: Just (TInterface Name { namespace = "Wp" , name = "Iterator" })
-- throws : False
-- Skip return : False

foreign import ccall "wp_iterator_ref" wp_iterator_ref :: 
    Ptr Iterator ->                         -- self : TInterface (Name {namespace = "Wp", name = "Iterator"})
    IO (Ptr Iterator)

-- | Increases the reference count of an iterator.
iteratorRef ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Iterator
    -- ^ /@self@/: an iterator object
    -> m Iterator
    -- ^ __Returns:__ /@self@/ with an additional reference count on it
iteratorRef self = liftIO $ do
    self' <- unsafeManagedPtrGetPtr self
    result <- wp_iterator_ref self'
    checkUnexpectedReturnNULL "iteratorRef" result
    result' <- (wrapBoxed Iterator) result
    touchManagedPtr self
    return result'

#if defined(ENABLE_OVERLOADING)
data IteratorRefMethodInfo
instance (signature ~ (m Iterator), MonadIO m) => O.OverloadedMethod IteratorRefMethodInfo Iterator signature where
    overloadedMethod = iteratorRef

instance O.OverloadedMethodInfo IteratorRefMethodInfo Iterator where
    overloadedMethodInfo = P.Just (O.ResolvedSymbolInfo {
        O.resolvedSymbolName = "GI.Wp.Structs.Iterator.iteratorRef",
        O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-wireplumber-0.5.14.2/docs/GI-Wp-Structs-Iterator.html#v:iteratorRef"
        })


#endif

-- method Iterator::reset
-- method type : OrdinaryMethod
-- Args: [ Arg
--           { argCName = "self"
--           , argType =
--               TInterface Name { namespace = "Wp" , name = "Iterator" }
--           , argCType = Just "WpIterator*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "the iterator" , sinceVersion = Nothing }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferNothing
--           }
--       ]
-- Lengths: []
-- returnType: Nothing
-- throws : False
-- Skip return : False

foreign import ccall "wp_iterator_reset" wp_iterator_reset :: 
    Ptr Iterator ->                         -- self : TInterface (Name {namespace = "Wp", name = "Iterator"})
    IO ()

-- | Resets the iterator so we can iterate again from the beginning.
iteratorReset ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Iterator
    -- ^ /@self@/: the iterator
    -> m ()
iteratorReset self = liftIO $ do
    self' <- unsafeManagedPtrGetPtr self
    wp_iterator_reset self'
    touchManagedPtr self
    return ()

#if defined(ENABLE_OVERLOADING)
data IteratorResetMethodInfo
instance (signature ~ (m ()), MonadIO m) => O.OverloadedMethod IteratorResetMethodInfo Iterator signature where
    overloadedMethod = iteratorReset

instance O.OverloadedMethodInfo IteratorResetMethodInfo Iterator where
    overloadedMethodInfo = P.Just (O.ResolvedSymbolInfo {
        O.resolvedSymbolName = "GI.Wp.Structs.Iterator.iteratorReset",
        O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-wireplumber-0.5.14.2/docs/GI-Wp-Structs-Iterator.html#v:iteratorReset"
        })


#endif

-- method Iterator::unref
-- method type : OrdinaryMethod
-- Args: [ Arg
--           { argCName = "self"
--           , argType =
--               TInterface Name { namespace = "Wp" , name = "Iterator" }
--           , argCType = Just "WpIterator*"
--           , direction = DirectionIn
--           , mayBeNull = False
--           , argDoc =
--               Documentation
--                 { rawDocText = Just "an iterator object" , sinceVersion = Nothing }
--           , argScope = ScopeTypeInvalid
--           , argClosure = -1
--           , argDestroy = -1
--           , argCallerAllocates = False
--           , argCallbackUserData = False
--           , transfer = TransferEverything
--           }
--       ]
-- Lengths: []
-- returnType: Nothing
-- throws : False
-- Skip return : False

foreign import ccall "wp_iterator_unref" wp_iterator_unref :: 
    Ptr Iterator ->                         -- self : TInterface (Name {namespace = "Wp", name = "Iterator"})
    IO ()

-- | Decreases the reference count on /@self@/ and frees it when the ref count reaches zero.
iteratorUnref ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Iterator
    -- ^ /@self@/: an iterator object
    -> m ()
iteratorUnref self = liftIO $ do
    self' <- B.ManagedPtr.disownBoxed self
    wp_iterator_unref self'
    touchManagedPtr self
    return ()

#if defined(ENABLE_OVERLOADING)
data IteratorUnrefMethodInfo
instance (signature ~ (m ()), MonadIO m) => O.OverloadedMethod IteratorUnrefMethodInfo Iterator signature where
    overloadedMethod = iteratorUnref

instance O.OverloadedMethodInfo IteratorUnrefMethodInfo Iterator where
    overloadedMethodInfo = P.Just (O.ResolvedSymbolInfo {
        O.resolvedSymbolName = "GI.Wp.Structs.Iterator.iteratorUnref",
        O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-wireplumber-0.5.14.2/docs/GI-Wp-Structs-Iterator.html#v:iteratorUnref"
        })


#endif

#if defined(ENABLE_OVERLOADING)
type family ResolveIteratorMethod (t :: Symbol) (o :: DK.Type) :: DK.Type where
    ResolveIteratorMethod "foreach" o = IteratorForeachMethodInfo
    ResolveIteratorMethod "next" o = IteratorNextMethodInfo
    ResolveIteratorMethod "ref" o = IteratorRefMethodInfo
    ResolveIteratorMethod "reset" o = IteratorResetMethodInfo
    ResolveIteratorMethod "unref" o = IteratorUnrefMethodInfo
    ResolveIteratorMethod "getUserData" o = IteratorGetUserDataMethodInfo
    ResolveIteratorMethod l o = O.MethodResolutionFailed l o

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

#if MIN_VERSION_base(4,13,0)
instance (info ~ ResolveIteratorMethod t Iterator, O.OverloadedMethod info Iterator p, R.HasField t Iterator p) => R.HasField t Iterator p where
    getField = O.overloadedMethod @info

#endif

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

#endif


