    {-# LANGUAGE CPP #-}
    {-# LANGUAGE GADTs #-}
    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE QuasiQuotes #-}
    {-# LANGUAGE RecordWildCards #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE TemplateHaskell #-}
    {-# LANGUAGE TypeFamilies #-}
    {-# LANGUAGE TypeOperators #-}

    -- | Enable painless embedding of C code in Haskell code. If you're interested
    -- in how to use the library, skip to the "Inline C" section. To build, read the
    -- first two sections.
    --
    -- This module is intended to be imported qualified:
    --
    -- @
    -- import qualified "Language.C.Inline" as C
    -- @

    module Language.C.Inline
      ( -- * GHCi
        -- $building

        -- * Contexts
        Context
      , baseCtx
      , fptrCtx
      , funCtx
      , vecCtx
      , bsCtx
      , context

        -- * Substitution
      , substitute
      , getHaskellType

        -- * Inline C
        -- $quoting
      , exp
      , pure
      , block
      , include
      , verbatim
      , emitBlock

        -- * 'Ptr' utils
      , withPtr
      , withPtr_
      , WithPtrs(..)

        -- * 'FunPtr' utils
      , funPtr
        -- ** 'FunPtr' conversion
        --
        -- Functions to quickly convert from/to 'FunPtr's. They're provided here
        -- since they can be useful to work with Haskell functions in C, and
        -- vice-versa. However, consider using 'funCtx' if you're doing this
        -- a lot.
      , mkFunPtr
      , mkFunPtrFromName
      , peekFunPtr

        -- * C types re-exports
        --
        -- Re-export these to avoid errors when `inline-c` generates FFI calls GHC
        -- needs the constructors for those types.
      , module Foreign.C.Types
      ) where

    #if __GLASGOW_HASKELL__ < 710
    import           Prelude hiding (exp)
    #else
    import           Prelude hiding (exp, pure)
    #endif

    import           Control.Monad (void)
    import           Foreign.C.Types
    import           Foreign.Marshal.Alloc (alloca)
    import           Foreign.Ptr (Ptr)
    import           Foreign.Storable (peek, Storable)
    import qualified Language.Haskell.TH as TH
    import qualified Language.Haskell.TH.Quote as TH

    import           Language.C.Inline.Context
    import           Language.C.Inline.Internal
    import           Language.C.Inline.FunPtr

    -- $building
    --
    -- Currently @inline-c@ does not work in interpreted mode. However, GHCi
    -- can still be used using the @-fobject-code@ flag. For speed, we
    -- reccomend passing @-fobject-code -O0@, for example
    --
    -- @
    -- stack ghci --ghci-options='-fobject-code -O0'
    -- @
    --
    -- or
    --
    -- @
    -- cabal repl --ghc-options='-fobject-code -O0'
    -- @

    ------------------------------------------------------------------------
    -- Quoting sugar

    -- $quoting
    --
    -- The quasiquoters below are the main interface to this library, for inlining
    -- C code into Haskell source files.
    --
    -- In general, quasiquoters are used like so:
    --
    -- @
    -- [C.XXX| int { \<C code\> } |]
    -- @
    --
    -- Where @C.XXX@ is one of the quasi-quoters defined in this section.
    --
    -- This syntax stands for a piece of typed C, decorated with a type:
    --
    -- * The first type to appear (@int@ in the example) is the type of said C code.
    --
    -- * The syntax of the @\<C code\>@ depends on on the quasi-quoter used, and the
    --   anti-quoters available. The @exp@ quasi-quoter expects a C expression. The
    --   @block@ quasi-quoter expects a list of statements, like the body of
    --   a function. Just like a C function, a block has a return type, matching the
    --   type of any values in any @return@ statements appearing in the block.
    --
    -- See also the @README.md@ file for more documentation.
    --
    -- === Anti-quoters
    --
    -- Haskell variables can be captured using anti-quoters.  @inline-c@
    -- provides a basic anti-quoting mechanism extensible with user-defined
    -- anti-quoters (see "Language.C.Inline.Context").  The basic
    -- anti-quoter lets you capture Haskell variables, for
    -- example we might say
    --
    -- @
    -- let x = pi / 3 in ['C.exp'| double { cos($(double x)) } |]
    -- @
    --
    -- Which would capture the Haskell variable @x@ of type @'CDouble'@.
    --
    -- In C expressions the @$@ character is denoted using @$$@.
    --
    -- === Variable capture and the typing relation
    --
    -- The Haskell type of the inlined expression is determined by the specified
    -- C return type. The relation between the C type and the Haskell type is
    -- defined in the current 'Context' -- see 'convertCType'. C pointers and
    -- arrays are both converted to Haskell @'Ptr'@s, and function pointers are
    -- converted to @'FunPtr'@s. Sized arrays are not supported.
    --
    -- Similarly, when capturing Haskell variables using anti-quoting, their
    -- type is assumed to be of the Haskell type corresponding to the C type
    -- provided.  For example, if we capture variable @x@ using @double x@
    -- in the parameter list, the code will expect a variable @x@ of type
    -- 'CDouble' in Haskell (when using 'baseCtx').
    --
    -- === Purity
    --
    -- The 'exp' and 'block' quasi-quotes denote computations in the 'IO' monad.
    -- 'pure' denotes a pure value, expressed as a C expression.
    --
    -- === Safe and @unsafe@ calls
    --
    -- @unsafe@ variants of the quasi-quoters are provided in
    -- "Language.C.Inline.Unsafe" to call the C code unsafely, in the sense that the
    -- C code will block the RTS, but with the advantage of a faster call to the
    -- foreign code. See
    -- <https://www.haskell.org/onlinereport/haskell2010/haskellch8.html#x15-1590008.4.3>.
    --
    -- == Examples
    --
    -- === Inline C expression
    --
    -- @
    -- {-\# LANGUAGE QuasiQuotes \#-}
    -- import qualified "Language.C.Inline" as C
    -- import qualified "Language.C.Inline.Unsafe" as CU
    -- import           "Foreign.C.Types"
    --
    -- C.'include' "\<math.h\>"
    --
    -- c_cos :: 'CDouble' -> IO 'CDouble'
    -- c_cos x = [C.exp| double { cos($(double x)) } |]
    --
    -- faster_c_cos :: 'CDouble' -> IO 'CDouble'
    -- faster_c_cos x = [CU.exp| double { cos($(double x)) } |]
    -- @
    --
    -- === Inline C statements
    --
    -- @
    -- {-\# LANGUAGE QuasiQuotes \#-}
    -- {-\# LANGUAGE TemplateHaskell \#-}
    -- import qualified Data.Vector.Storable.Mutable as V
    -- import qualified "Language.C.Inline" as C
    -- import           "Foreign.C.Types"
    --
    -- C.'include' "\<stdio.h\>"
    --
    -- parseVector :: 'CInt' -> 'IO' (V.IOVector 'CDouble')
    -- parseVector len = do
    --   vec <- V.new $ 'fromIntegral' len0
    --   V.unsafeWith vec $ \\ptr -> [C.'block'| void {
    --     int i;
    --     for (i = 0; i < $(int len); i++) {
    --       scanf("%lf ", &$(double *ptr)[i]);
    --     }
    --   } |]
    --   'return' vec
    -- @
    --
    -- == How it works
    --
    -- For each quasi-quotation of C code, a C function is generated in a C file
    -- corresponding to the current Haskell file. Every inline C expression will result
    -- in a corresponding C function.
    -- For example, if we define @c_cos@
    -- as in the example above in @CCos.hs@, we will get a file containing
    --
    -- @
    -- #include <math.h>
    --
    -- double inline_c_Main_0_a03fba228a6d8e36ea7d69381f87bade594c949d(double x_inline_c_0) {
    --   return cos(x_inline_c_0);
    -- }
    -- @
    --
    -- Every anti-quotation will correspond to an argument in the C function. If the same
    -- Haskell variable is anti-quoted twice, this will result in two arguments.
    --
    -- The C function is then automatically compiled and invoked from Haskell with the correct arguments passed in.

    -- | C expressions.
    exp :: TH.QuasiQuoter
    exp :: QuasiQuoter
    exp = Purity
    -> (Loc
        -> TypeQ
        -> Type CIdentifier
        -> [(CIdentifier, Type CIdentifier)]
        -> [Char]
        -> ExpQ)
    -> QuasiQuoter
    genericQuote Purity
    IO ((Loc
      -> TypeQ
      -> Type CIdentifier
      -> [(CIdentifier, Type CIdentifier)]
      -> [Char]
      -> ExpQ)
     -> QuasiQuoter)
    -> (Loc
        -> TypeQ
        -> Type CIdentifier
        -> [(CIdentifier, Type CIdentifier)]
        -> [Char]
        -> ExpQ)
    -> QuasiQuoter
    forall a b. (a -> b) -> a -> b
    $ Safety
    -> Loc
    -> TypeQ
    -> Type CIdentifier
    -> [(CIdentifier, Type CIdentifier)]
    -> [Char]
    -> ExpQ
    inlineExp Safety
    TH.Safe

    -- | Variant of 'exp', for use with expressions known to have no side effects.
    --
    -- __BEWARE__: Use this function with caution, only when you know what you are
    -- doing. If an expression does in fact have side-effects, then indiscriminate
    -- use of 'pure' may endanger referential transparency, and in principle even
    -- type safety. Also note that the function might be called multiple times,
    -- given that 'System.IO.Unsafe.unsafeDupablePerformIO' is used to call the
    -- provided C code.  Please refer to the documentation for
    -- 'System.IO.Unsafe.unsafePerformIO' for more details.
    -- [unsafeDupablePerformIO is used to ensure good performance using the
    -- threaded runtime](https://github.com/fpco/inline-c/issues/115).
    pure :: TH.QuasiQuoter
    pure :: QuasiQuoter
    pure = Purity
    -> (Loc
        -> TypeQ
        -> Type CIdentifier
        -> [(CIdentifier, Type CIdentifier)]
        -> [Char]
        -> ExpQ)
    -> QuasiQuoter
    genericQuote Purity
    Pure ((Loc
      -> TypeQ
      -> Type CIdentifier
      -> [(CIdentifier, Type CIdentifier)]
      -> [Char]
      -> ExpQ)
     -> QuasiQuoter)
    -> (Loc
        -> TypeQ
        -> Type CIdentifier
        -> [(CIdentifier, Type CIdentifier)]
        -> [Char]
        -> ExpQ)
    -> QuasiQuoter
    forall a b. (a -> b) -> a -> b
    $ Safety
    -> Loc
    -> TypeQ
    -> Type CIdentifier
    -> [(CIdentifier, Type CIdentifier)]
    -> [Char]
    -> ExpQ
    inlineExp Safety
    TH.Safe

    -- | C code blocks (i.e. statements).
    block :: TH.QuasiQuoter
    block :: QuasiQuoter
    block = Purity
    -> (Loc
        -> TypeQ
        -> Type CIdentifier
        -> [(CIdentifier, Type CIdentifier)]
        -> [Char]
        -> ExpQ)
    -> QuasiQuoter
    genericQuote Purity
    IO ((Loc
      -> TypeQ
      -> Type CIdentifier
      -> [(CIdentifier, Type CIdentifier)]
      -> [Char]
      -> ExpQ)
     -> QuasiQuoter)
    -> (Loc
        -> TypeQ
        -> Type CIdentifier
        -> [(CIdentifier, Type CIdentifier)]
        -> [Char]
        -> ExpQ)
    -> QuasiQuoter
    forall a b. (a -> b) -> a -> b
    $ Safety
    -> Bool
    -> Maybe [Char]
    -> Loc
    -> TypeQ
    -> Type CIdentifier
    -> [(CIdentifier, Type CIdentifier)]
    -> [Char]
    -> ExpQ
    inlineItems Safety
    TH.Safe Bool
    False Maybe [Char]
    forall a. Maybe a
    Nothing

    -- | Easily get a 'FunPtr':
    --
    -- @
    -- let fp :: FunPtr (Ptr CInt -> IO ()) = [C.funPtr| void poke42(int *ptr) { *ptr = 42; } |]
    -- @
    --
    -- Especially useful to generate finalizers that require C code.
    --
    -- Most importantly, this allows you to write `Foreign.ForeignPtr.newForeignPtr` invocations conveniently:
    --
    -- @
    -- do
    --   let c_finalizer_funPtr =
    --         [C.funPtr| void myfree(char * ptr) { free(ptr); } |]
    --   fp <- newForeignPtr c_finalizer_funPtr objPtr
    -- @
    --
    -- Using where possible `Foreign.ForeignPtr.newForeignPtr` is superior to
    -- resorting to its delayed-by-a-thread alternative `Foreign.Concurrent.newForeignPtr`
    -- from "Foreign.Concurrent" which takes an @IO ()@ Haskell finaliser action:
    -- With the non-concurrent `newForeignPtr` you can guarantee that the finaliser
    -- will actually be run
    --
    -- * when a GC is executed under memory pressure, because it can point directly
    --   to a C function that doesn't have to run any Haskell code (which is
    --   problematic when you're out of memory)
    -- * when the program terminates (`Foreign.Concurrent.newForeignPtr`'s finaliser
    --   will likely NOT be called if your main thread exits, making your program
    --   e.g. not Valgrind-clean if your finaliser is @free@ or C++'s @delete@).
    --
    -- `funPtr` makes the normal `newForeignPtr` as convenient as its concurrent
    -- counterpart.
    funPtr :: TH.QuasiQuoter
    funPtr :: QuasiQuoter
    funPtr = Safety -> QuasiQuoter
    funPtrQuote Safety
    TH.Unsafe -- doesn't make much sense for this to be "safe", but it'd be good to verify what this means

    -- | Emits a CPP include directive for C code associated with the current
    -- module. To avoid having to escape quotes, the function itself adds them when
    -- appropriate, so that
    --
    -- @
    -- include "foo.h" ==> #include "foo.h"
    -- @
    --
    -- but
    --
    -- @
    -- include "\<foo\>" ==> #include \<foo\>
    -- @
    include :: String -> TH.DecsQ
    include :: [Char] -> DecsQ
    include [Char]
    s
      | [Char] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Char]
    s = [Char] -> DecsQ
    forall a. [Char] -> Q a
    forall (m :: * -> *) a. MonadFail m => [Char] -> m a
    fail [Char]
    "inline-c: empty string (include)"
      | [Char] -> Char
    forall a. HasCallStack => [a] -> a
    head [Char]
    s Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '<' = [Char] -> DecsQ
    verbatim ([Char] -> DecsQ) -> [Char] -> DecsQ
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "#include " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    s
      | Bool
    otherwise = [Char] -> DecsQ
    verbatim ([Char] -> DecsQ) -> [Char] -> DecsQ
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "#include \"" [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    s [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "\""

    -- | Emits an arbitrary C string to the C code associated with the
    -- current module.  Use with care.
    verbatim :: String -> TH.DecsQ
    verbatim :: [Char] -> DecsQ
    verbatim [Char]
    s = do
      DecsQ -> Q ()
    forall (f :: * -> *) a. Functor f => f a -> f ()
    void (DecsQ -> Q ()) -> DecsQ -> Q ()
    forall a b. (a -> b) -> a -> b
    $ [Char] -> DecsQ
    emitVerbatim [Char]
    s
      [Dec] -> DecsQ
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return []

    ------------------------------------------------------------------------
    -- 'Ptr' utils

    -- | Like 'alloca', but also peeks the contents of the 'Ptr' and returns
    -- them once the provided action has finished.
    withPtr :: (Storable a) => (Ptr a -> IO b) -> IO (a, b)
    withPtr :: forall a b. Storable a => (Ptr a -> IO b) -> IO (a, b)
    withPtr Ptr a -> IO b
    f = do
      (Ptr a -> IO (a, b)) -> IO (a, b)
    forall a b. Storable a => (Ptr a -> IO b) -> IO b
    alloca ((Ptr a -> IO (a, b)) -> IO (a, b))
    -> (Ptr a -> IO (a, b)) -> IO (a, b)
    forall a b. (a -> b) -> a -> b
    $ \Ptr a
    ptr -> do
        x <- Ptr a -> IO b
    f Ptr a
    ptr
        y <- peek ptr
        return (y, x)

    withPtr_ :: (Storable a) => (Ptr a -> IO ()) -> IO a
    withPtr_ :: forall a. Storable a => (Ptr a -> IO ()) -> IO a
    withPtr_ Ptr a -> IO ()
    f = do
      (x, ()) <- (Ptr a -> IO ()) -> IO (a, ())
    forall a b. Storable a => (Ptr a -> IO b) -> IO (a, b)
    withPtr Ptr a -> IO ()
    f
      return x

    -- | Type class with methods useful to allocate and peek multiple
    -- pointers at once:
    --
    -- @
    -- withPtrs_ :: (Storable a, Storable b) => ((Ptr a, Ptr b) -> IO ()) -> IO (a, b)
    -- withPtrs_ :: (Storable a, Storable b, Storable c) => ((Ptr a, Ptr b, Ptr c) -> IO ()) -> IO (a, b, c)
    -- ...
    -- @
    class WithPtrs a where
      type WithPtrsPtrs a :: *
      withPtrs :: (WithPtrsPtrs a -> IO b) -> IO (a, b)

      withPtrs_ :: (WithPtrsPtrs a -> IO ()) -> IO a
      withPtrs_ WithPtrsPtrs a -> IO ()
    f = do
        (x, _) <- (WithPtrsPtrs a -> IO ()) -> IO (a, ())
    forall a b. WithPtrs a => (WithPtrsPtrs a -> IO b) -> IO (a, b)
    forall b. (WithPtrsPtrs a -> IO b) -> IO (a, b)
    withPtrs WithPtrsPtrs a -> IO ()
    f
        return x

    instance (Storable a, Storable b) => WithPtrs (a, b) where
      type WithPtrsPtrs (a, b) = (Ptr a, Ptr b)
      withPtrs :: forall b. (WithPtrsPtrs (a, b) -> IO b) -> IO ((a, b), b)
    withPtrs WithPtrsPtrs (a, b) -> IO b
    f = do
        (a, (b, x)) <- (Ptr a -> IO (b, b)) -> IO (a, (b, b))
    forall a b. Storable a => (Ptr a -> IO b) -> IO (a, b)
    withPtr ((Ptr a -> IO (b, b)) -> IO (a, (b, b)))
    -> (Ptr a -> IO (b, b)) -> IO (a, (b, b))
    forall a b. (a -> b) -> a -> b
    $ \Ptr a
    a -> (Ptr b -> IO b) -> IO (b, b)
    forall a b. Storable a => (Ptr a -> IO b) -> IO (a, b)
    withPtr ((Ptr b -> IO b) -> IO (b, b)) -> (Ptr b -> IO b) -> IO (b, b)
    forall a b. (a -> b) -> a -> b
    $ \Ptr b
    b -> WithPtrsPtrs (a, b) -> IO b
    f (Ptr a
    a, Ptr b
    b)
        return ((a, b), x)

    instance (Storable a, Storable b, Storable c) => WithPtrs (a, b, c) where
      type WithPtrsPtrs (a, b, c) = (Ptr a, Ptr b, Ptr c)
      withPtrs :: forall b. (WithPtrsPtrs (a, b, c) -> IO b) -> IO ((a, b, c), b)
    withPtrs WithPtrsPtrs (a, b, c) -> IO b
    f = do
        (a, ((b, c), x)) <- (Ptr a -> IO ((b, c), b)) -> IO (a, ((b, c), b))
    forall a b. Storable a => (Ptr a -> IO b) -> IO (a, b)
    withPtr ((Ptr a -> IO ((b, c), b)) -> IO (a, ((b, c), b)))
    -> (Ptr a -> IO ((b, c), b)) -> IO (a, ((b, c), b))
    forall a b. (a -> b) -> a -> b
    $ \Ptr a
    a -> (WithPtrsPtrs (b, c) -> IO b) -> IO ((b, c), b)
    forall a b. WithPtrs a => (WithPtrsPtrs a -> IO b) -> IO (a, b)
    forall b. (WithPtrsPtrs (b, c) -> IO b) -> IO ((b, c), b)
    withPtrs ((WithPtrsPtrs (b, c) -> IO b) -> IO ((b, c), b))
    -> (WithPtrsPtrs (b, c) -> IO b) -> IO ((b, c), b)
    forall a b. (a -> b) -> a -> b
    $ \(Ptr b
    b, Ptr c
    c) -> WithPtrsPtrs (a, b, c) -> IO b
    f (Ptr a
    a, Ptr b
    b, Ptr c
    c)
        return ((a, b, c), x)

    instance (Storable a, Storable b, Storable c, Storable d) => WithPtrs (a, b, c, d) where
      type WithPtrsPtrs (a, b, c, d) = (Ptr a, Ptr b, Ptr c, Ptr d)
      withPtrs :: forall b.
    (WithPtrsPtrs (a, b, c, d) -> IO b) -> IO ((a, b, c, d), b)
    withPtrs WithPtrsPtrs (a, b, c, d) -> IO b
    f = do
        (a, ((b, c, d), x)) <- (Ptr a -> IO ((b, c, d), b)) -> IO (a, ((b, c, d), b))
    forall a b. Storable a => (Ptr a -> IO b) -> IO (a, b)
    withPtr ((Ptr a -> IO ((b, c, d), b)) -> IO (a, ((b, c, d), b)))
    -> (Ptr a -> IO ((b, c, d), b)) -> IO (a, ((b, c, d), b))
    forall a b. (a -> b) -> a -> b
    $ \Ptr a
    a -> (WithPtrsPtrs (b, c, d) -> IO b) -> IO ((b, c, d), b)
    forall a b. WithPtrs a => (WithPtrsPtrs a -> IO b) -> IO (a, b)
    forall b. (WithPtrsPtrs (b, c, d) -> IO b) -> IO ((b, c, d), b)
    withPtrs ((WithPtrsPtrs (b, c, d) -> IO b) -> IO ((b, c, d), b))
    -> (WithPtrsPtrs (b, c, d) -> IO b) -> IO ((b, c, d), b)
    forall a b. (a -> b) -> a -> b
    $ \(Ptr b
    b, Ptr c
    c, Ptr d
    d) -> WithPtrsPtrs (a, b, c, d) -> IO b
    f (Ptr a
    a, Ptr b
    b, Ptr c
    c, Ptr d
    d)
        return ((a, b, c, d), x)

    instance (Storable a, Storable b, Storable c, Storable d, Storable e) => WithPtrs (a, b, c, d, e) where
      type WithPtrsPtrs (a, b, c, d, e) = (Ptr a, Ptr b, Ptr c, Ptr d, Ptr e)
      withPtrs :: forall b.
    (WithPtrsPtrs (a, b, c, d, e) -> IO b) -> IO ((a, b, c, d, e), b)
    withPtrs WithPtrsPtrs (a, b, c, d, e) -> IO b
    f = do
        (a, ((b, c, d, e), x)) <- (Ptr a -> IO ((b, c, d, e), b)) -> IO (a, ((b, c, d, e), b))
    forall a b. Storable a => (Ptr a -> IO b) -> IO (a, b)
    withPtr ((Ptr a -> IO ((b, c, d, e), b)) -> IO (a, ((b, c, d, e), b)))
    -> (Ptr a -> IO ((b, c, d, e), b)) -> IO (a, ((b, c, d, e), b))
    forall a b. (a -> b) -> a -> b
    $ \Ptr a
    a -> (WithPtrsPtrs (b, c, d, e) -> IO b) -> IO ((b, c, d, e), b)
    forall a b. WithPtrs a => (WithPtrsPtrs a -> IO b) -> IO (a, b)
    forall b.
    (WithPtrsPtrs (b, c, d, e) -> IO b) -> IO ((b, c, d, e), b)
    withPtrs ((WithPtrsPtrs (b, c, d, e) -> IO b) -> IO ((b, c, d, e), b))
    -> (WithPtrsPtrs (b, c, d, e) -> IO b) -> IO ((b, c, d, e), b)
    forall a b. (a -> b) -> a -> b
    $ \(Ptr b
    b, Ptr c
    c, Ptr d
    d, Ptr e
    e) -> WithPtrsPtrs (a, b, c, d, e) -> IO b
    f (Ptr a
    a, Ptr b
    b, Ptr c
    c, Ptr d
    d, Ptr e
    e)
        return ((a, b, c, d, e), x)

    instance (Storable a, Storable b, Storable c, Storable d, Storable e, Storable f) => WithPtrs (a, b, c, d, e, f) where
      type WithPtrsPtrs (a, b, c, d, e, f) = (Ptr a, Ptr b, Ptr c, Ptr d, Ptr e, Ptr f)
      withPtrs :: forall b.
    (WithPtrsPtrs (a, b, c, d, e, f) -> IO b)
    -> IO ((a, b, c, d, e, f), b)
    withPtrs WithPtrsPtrs (a, b, c, d, e, f) -> IO b
    fun = do
        (a, ((b, c, d, e, f), x)) <- (Ptr a -> IO ((b, c, d, e, f), b)) -> IO (a, ((b, c, d, e, f), b))
    forall a b. Storable a => (Ptr a -> IO b) -> IO (a, b)
    withPtr ((Ptr a -> IO ((b, c, d, e, f), b))
     -> IO (a, ((b, c, d, e, f), b)))
    -> (Ptr a -> IO ((b, c, d, e, f), b))
    -> IO (a, ((b, c, d, e, f), b))
    forall a b. (a -> b) -> a -> b
    $ \Ptr a
    a -> (WithPtrsPtrs (b, c, d, e, f) -> IO b) -> IO ((b, c, d, e, f), b)
    forall a b. WithPtrs a => (WithPtrsPtrs a -> IO b) -> IO (a, b)
    forall b.
    (WithPtrsPtrs (b, c, d, e, f) -> IO b) -> IO ((b, c, d, e, f), b)
    withPtrs ((WithPtrsPtrs (b, c, d, e, f) -> IO b) -> IO ((b, c, d, e, f), b))
    -> (WithPtrsPtrs (b, c, d, e, f) -> IO b)
    -> IO ((b, c, d, e, f), b)
    forall a b. (a -> b) -> a -> b
    $ \(Ptr b
    b, Ptr c
    c, Ptr d
    d, Ptr e
    e, Ptr f
    f) -> WithPtrsPtrs (a, b, c, d, e, f) -> IO b
    fun (Ptr a
    a, Ptr b
    b, Ptr c
    c, Ptr d
    d, Ptr e
    e, Ptr f
    f)
        return ((a, b, c, d, e, f), x)

    instance (Storable a, Storable b, Storable c, Storable d, Storable e, Storable f, Storable g) => WithPtrs (a, b, c, d, e, f, g) where
      type WithPtrsPtrs (a, b, c, d, e, f, g) = (Ptr a, Ptr b, Ptr c, Ptr d, Ptr e, Ptr f, Ptr g)
      withPtrs :: forall b.
    (WithPtrsPtrs (a, b, c, d, e, f, g) -> IO b)
    -> IO ((a, b, c, d, e, f, g), b)
    withPtrs WithPtrsPtrs (a, b, c, d, e, f, g) -> IO b
    fun = do
        (a, ((b, c, d, e, f, g), x)) <- (Ptr a -> IO ((b, c, d, e, f, g), b))
    -> IO (a, ((b, c, d, e, f, g), b))
    forall a b. Storable a => (Ptr a -> IO b) -> IO (a, b)
    withPtr ((Ptr a -> IO ((b, c, d, e, f, g), b))
     -> IO (a, ((b, c, d, e, f, g), b)))
    -> (Ptr a -> IO ((b, c, d, e, f, g), b))
    -> IO (a, ((b, c, d, e, f, g), b))
    forall a b. (a -> b) -> a -> b
    $ \Ptr a
    a -> (WithPtrsPtrs (b, c, d, e, f, g) -> IO b)
    -> IO ((b, c, d, e, f, g), b)
    forall a b. WithPtrs a => (WithPtrsPtrs a -> IO b) -> IO (a, b)
    forall b.
    (WithPtrsPtrs (b, c, d, e, f, g) -> IO b)
    -> IO ((b, c, d, e, f, g), b)
    withPtrs ((WithPtrsPtrs (b, c, d, e, f, g) -> IO b)
     -> IO ((b, c, d, e, f, g), b))
    -> (WithPtrsPtrs (b, c, d, e, f, g) -> IO b)
    -> IO ((b, c, d, e, f, g), b)
    forall a b. (a -> b) -> a -> b
    $ \(Ptr b
    b, Ptr c
    c, Ptr d
    d, Ptr e
    e, Ptr f
    f, Ptr g
    g) -> WithPtrsPtrs (a, b, c, d, e, f, g) -> IO b
    fun (Ptr a
    a, Ptr b
    b, Ptr c
    c, Ptr d
    d, Ptr e
    e, Ptr f
    f, Ptr g
    g)
        return ((a, b, c, d, e, f, g), x)

    ------------------------------------------------------------------------
    -- setContext alias

    -- | Sets the 'Context' for the current module.  This function, if
    -- called, must be called before any of the other TH functions in this
    -- module.  Fails if that's not the case.
    context :: Context -> TH.DecsQ
    context :: Context -> DecsQ
    context Context
    ctx = do
      Context -> Q ()
    setContext Context
    ctx
      [Dec] -> DecsQ
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return []