{-# LANGUAGE DataKinds #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleInstances #-}

module Torch.Internal.Unmanaged.Type.C10Dict where


import qualified Language.C.Inline.Cpp as C
import qualified Language.C.Inline.Cpp.Unsafe as C
import qualified Language.C.Inline.Context as C
import qualified Language.C.Types as C
import qualified Data.Map as Map
import Foreign.C.String
import Foreign.C.Types
import Foreign
import Torch.Internal.Type
import Control.Monad (forM)
import Control.Exception.Safe (bracket)

C.context $ C.cppCtx <> mempty { C.ctxTypesTable = typeTable }

C.include "<ATen/core/Dict.h>"
C.include "<vector>"

newC10Dict :: Ptr IValue -> Ptr IValue -> IO (Ptr (C10Dict '(IValue,IValue)))
newC10Dict :: Ptr IValue -> Ptr IValue -> IO (Ptr (C10Dict '(IValue, IValue)))
newC10Dict Ptr IValue
key Ptr IValue
value = [C.throwBlock| c10::Dict<at::IValue,at::IValue>* {
  return new c10::impl::GenericDict($(at::IValue* key)->type(),$(at::IValue* value)->type());
}|]

c10Dict_empty :: Ptr (C10Dict '(IValue,IValue)) -> IO (CBool)
c10Dict_empty :: Ptr (C10Dict '(IValue, IValue)) -> IO CBool
c10Dict_empty Ptr (C10Dict '(IValue, IValue))
_obj = [C.throwBlock| bool { return (*$(c10::Dict<at::IValue,at::IValue>* _obj)).empty(); }|]

c10Dict_size :: Ptr (C10Dict '(IValue,IValue)) -> IO (CSize)
c10Dict_size :: Ptr (C10Dict '(IValue, IValue)) -> IO CSize
c10Dict_size Ptr (C10Dict '(IValue, IValue))
_obj = [C.throwBlock| size_t { return (*$(c10::Dict<at::IValue,at::IValue>* _obj)).size(); }|]

c10Dict_at :: Ptr (C10Dict '(IValue,IValue)) -> Ptr IValue -> IO (Ptr IValue)
c10Dict_at :: Ptr (C10Dict '(IValue, IValue)) -> Ptr IValue -> IO (Ptr IValue)
c10Dict_at Ptr (C10Dict '(IValue, IValue))
_obj Ptr IValue
_s = [C.throwBlock| at::IValue* { return new at::IValue((*$(c10::Dict<at::IValue,at::IValue>* _obj)).at(*$(at::IValue* _s))); }|]

c10Dict_insert :: Ptr (C10Dict '(IValue,IValue)) -> Ptr IValue  -> Ptr IValue -> IO ()
c10Dict_insert :: Ptr (C10Dict '(IValue, IValue))
-> Ptr IValue -> Ptr IValue -> IO ()
c10Dict_insert Ptr (C10Dict '(IValue, IValue))
_obj Ptr IValue
_key Ptr IValue
_value =
  [C.throwBlock| void {
    (*$(c10::Dict<at::IValue,at::IValue>* _obj)).insert(*$(at::IValue* _key),*$(at::IValue* _value));
  }|]

c10Dict_toList :: Ptr (C10Dict '(IValue,IValue)) -> IO [(Ptr IValue,Ptr IValue)]
c10Dict_toList :: Ptr (C10Dict '(IValue, IValue)) -> IO [(Ptr IValue, Ptr IValue)]
c10Dict_toList Ptr (C10Dict '(IValue, IValue))
_obj = do
  let new :: IO (Ptr (StdVector (StdArray '(IValue, 2))))
new = [C.throwBlock| std::vector<std::array<at::IValue,2>>* {
              auto obj = *$(c10::Dict<at::IValue,at::IValue>* _obj);
              auto ret = new std::vector<std::array<at::IValue,2> >();
              for(auto i = obj.begin() ; i != obj.end() ; i++){
                ret->push_back({i->key(),i->value()});
              }
              return ret;
             }|]
      free :: Ptr (StdVector (StdArray '(IValue, 2))) -> IO ()
free Ptr (StdVector (StdArray '(IValue, 2)))
dat = [C.throwBlock| void {
              delete $(std::vector<std::array<at::IValue,2>>* dat);
             }|]
  forall (m :: * -> *) a b c.
MonadMask m =>
m a -> (a -> m b) -> (a -> m c) -> m c
bracket IO (Ptr (StdVector (StdArray '(IValue, 2))))
new Ptr (StdVector (StdArray '(IValue, 2))) -> IO ()
free forall a b. (a -> b) -> a -> b
$ \Ptr (StdVector (StdArray '(IValue, 2)))
dat -> do
    Int64
size <- [C.throwBlock| int64_t { return (long int)$(std::vector<std::array<at::IValue,2>>* dat)->size();}|]
    [(Ptr IValue, Ptr IValue)]
ret <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [Int64
0..(Int64
sizeforall a. Num a => a -> a -> a
-Int64
1)] forall a b. (a -> b) -> a -> b
$ \Int64
i -> do
      Ptr IValue
key <- [C.throwBlock| at::IValue* { return new at::IValue($(std::vector<std::array<at::IValue,2>>* dat)->at($(int64_t i))[0]);}|]
      Ptr IValue
val <- [C.throwBlock| at::IValue* { return new at::IValue($(std::vector<std::array<at::IValue,2>>* dat)->at($(int64_t i))[1]);}|]
      forall (m :: * -> *) a. Monad m => a -> m a
return (Ptr IValue
key,Ptr IValue
val)
    forall (m :: * -> *) a. Monad m => a -> m a
return [(Ptr IValue, Ptr IValue)]
ret