{-# LANGUAGE TemplateHaskell #-} module STD.MapIterator.TH where import Data.Char import Data.List import Data.Monoid import Foreign.C.Types import Foreign.Ptr import Language.Haskell.TH import Language.Haskell.TH.Syntax import FFICXX.Runtime.CodeGen.Cxx import FFICXX.Runtime.TH import STD.MapIterator.Template import STD.Pair.Template t_deRef :: (Type, Type) -> String -> Q Exp t_deRef (typ1, typ2) suffix = mkTFunc ((typ1, typ2), suffix, \ n -> "MapIterator_deRef" <> n, tyf) where tyf _ = let tpk = pure typ1 tpv = pure typ2 in [t| MapIterator $( tpk ) $( tpv ) -> IO (Pair $( tpk ) $( tpv )) |] t_increment :: (Type, Type) -> String -> Q Exp t_increment (typ1, typ2) suffix = mkTFunc ((typ1, typ2), suffix, \ n -> "MapIterator_increment" <> n, tyf) where tyf _ = let tpk = pure typ1 tpv = pure typ2 in [t| MapIterator $( tpk ) $( tpv ) -> IO (MapIterator $( tpk ) $( tpv )) |] genMapIteratorInstanceFor :: IsCPrimitive -> (Q Type, TemplateParamInfo) -> (Q Type, TemplateParamInfo) -> Q [Dec] genMapIteratorInstanceFor isCprim (qtyp1, param1) (qtyp2, param2) = do let params = map tpinfoSuffix [param1, param2] let suffix = concatMap (\ x -> "_" ++ tpinfoSuffix x) [param1, param2] callmod_ <- fmap loc_module location let callmod = dot2_ callmod_ typ1 <- qtyp1 typ2 <- qtyp2 f1 <- mkMember "deRef" t_deRef (typ1, typ2) suffix f2 <- mkMember "increment" t_increment (typ1, typ2) suffix addModFinalizer (addForeignSource LangCxx ("\n#include \"MacroPatternMatch.h\"\n\n\n#include \"map\"\n\n\n#define MapIterator_deRef(callmod, tpk, tpv) \\\nextern \"C\" {\\\nvoid* MapIterator_deRef_##tpk##_##tpv ( void* p );}\\\ninline void* MapIterator_deRef_##tpk##_##tpv ( void* p ) {\\\nstd::pair* r=new std::pair((static_cast::iterator*>(p))->operator*());return static_cast(r);\\\n}\\\nauto a_##callmod##_MapIterator_deRef_##tpk##_##tpv=MapIterator_deRef_##tpk##_##tpv;\n\n\n#define MapIterator_increment(callmod, tpk, tpv) \\\nextern \"C\" {\\\nvoid* MapIterator_increment_##tpk##_##tpv ( void* p );}\\\ninline void* MapIterator_increment_##tpk##_##tpv ( void* p ) {\\\nstd::map::iterator* r=new std::map::iterator((static_cast::iterator*>(p))->operator++());return static_cast(r);\\\n}\\\nauto a_##callmod##_MapIterator_increment_##tpk##_##tpv=MapIterator_increment_##tpk##_##tpv;\n\n\n#define MapIterator_deRef_s(callmod, tpk, tpv) \\\nextern \"C\" {\\\nvoid* MapIterator_deRef_##tpk##_##tpv ( void* p );}\\\ninline void* MapIterator_deRef_##tpk##_##tpv ( void* p ) {\\\nstd::pair* r=new std::pair((static_cast::iterator*>(p))->operator*());return static_cast(r);\\\n}\\\nauto a_##callmod##_MapIterator_deRef_##tpk##_##tpv=MapIterator_deRef_##tpk##_##tpv;\n\n\n#define MapIterator_increment_s(callmod, tpk, tpv) \\\nextern \"C\" {\\\nvoid* MapIterator_increment_##tpk##_##tpv ( void* p );}\\\ninline void* MapIterator_increment_##tpk##_##tpv ( void* p ) {\\\nstd::map::iterator* r=new std::map::iterator((static_cast::iterator*>(p))->operator++());return static_cast(r);\\\n}\\\nauto a_##callmod##_MapIterator_increment_##tpk##_##tpv=MapIterator_increment_##tpk##_##tpv;\n\n\n#define MapIterator_instance(callmod, tpk, tpv) \\\nMapIterator_deRef(callmod, tpk, tpv)\\\nMapIterator_increment(callmod, tpk, tpv)\n\n\n#define MapIterator_instance_s(callmod, tpk, tpv) \\\nMapIterator_deRef_s(callmod, tpk, tpv)\\\nMapIterator_increment_s(callmod, tpk, tpv)\n\n" ++ let headers = concatMap tpinfoCxxHeaders [param1, param2] f x = renderCMacro (Include x) in concatMap f headers ++ let nss = concatMap tpinfoCxxNamespaces [param1, param2] f x = renderCStmt (UsingNamespace x) in concatMap f nss ++ "MapIterator_instance" ++ (case isCprim of CPrim -> "_s" NonCPrim -> "") ++ "(" ++ intercalate ", " (callmod : params) ++ ")\n")) let lst = [f1, f2] pure [mkInstance [] (AppT (AppT (con "IMapIterator") typ1) typ2) lst]