bond 0.10.0.0 → 0.10.1.0
raw patch · 13 files changed
+166/−32 lines, 13 filesnew-uploaderPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Language.Bond.Codegen.Templates: grpc_cpp :: MappingContext -> String -> [Import] -> [Declaration] -> (String, Text)
Files
- Main.hs +1/−1
- bond.cabal +14/−1
- src/Language/Bond/Codegen/Cpp/Comm_cpp.hs +0/−1
- src/Language/Bond/Codegen/Cpp/Grpc_cpp.hs +33/−0
- src/Language/Bond/Codegen/Cpp/Grpc_h.hs +69/−7
- src/Language/Bond/Codegen/Cpp/Types_h.hs +17/−7
- src/Language/Bond/Codegen/Cs/Comm_cs.hs +12/−6
- src/Language/Bond/Codegen/Cs/Grpc_cs.hs +6/−4
- src/Language/Bond/Codegen/Cs/Util.hs +3/−1
- src/Language/Bond/Codegen/Templates.hs +2/−0
- src/Language/Bond/Codegen/TypeMapping.hs +4/−4
- tests/TestMain.hs +4/−0
- tests/Tests/Codegen.hs +1/−0
Main.hs view
@@ -87,7 +87,7 @@ templates = concat $ map snd $ filter fst codegen_templates codegen_templates = [ (core_enabled, core_files) , (comm_enabled, [comm_h export_attribute, comm_cpp]) - , (grpc_enabled, [grpc_h export_attribute]) + , (grpc_enabled, [grpc_h export_attribute, grpc_cpp]) ] core_files = [ reflection_h export_attribute
bond.cabal view
@@ -2,7 +2,7 @@ -- Licensed under the MIT license. See LICENSE file in the project root for full license information. name: bond -version: 0.10.0.0 +version: 0.10.1.0 cabal-version: >= 1.8 tested-with: GHC>=7.4.1 synopsis: Bond schema compiler and code generator @@ -65,6 +65,7 @@ Language.Bond.Codegen.Cpp.Types_h Language.Bond.Codegen.Cpp.Comm_cpp Language.Bond.Codegen.Cpp.Comm_h + Language.Bond.Codegen.Cpp.Grpc_cpp Language.Bond.Codegen.Cpp.Grpc_h Language.Bond.Codegen.Cs.Types_cs Language.Bond.Codegen.Cs.Comm_cs @@ -86,6 +87,12 @@ Tests.Codegen.Util Tests.Syntax ghc-options: -threaded -Wall + + if os(windows) && arch(i386) + ld-options: -Wl,--dynamicbase -Wl,--nxcompat -Wl,--large-address-aware + if os(windows) && arch(x86_64) + ld-options: -Wl,--dynamicbase -Wl,--nxcompat -Wl,--high-entropy-va + build-depends: bond, aeson >= 0.7.0.6 && < 0.12.0.0, aeson-pretty == 0.7.2, @@ -112,6 +119,12 @@ other-modules: IO Options ghc-options: -threaded -Wall + + if os(windows) && arch(i386) + ld-options: -Wl,--dynamicbase -Wl,--nxcompat -Wl,--large-address-aware + if os(windows) && arch(x86_64) + ld-options: -Wl,--dynamicbase -Wl,--nxcompat -Wl,--high-entropy-va + build-depends: bond, aeson >= 0.7.0.6 && < 0.12.0.0, async >= 2.0.1.0,
src/Language/Bond/Codegen/Cpp/Comm_cpp.hs view
@@ -20,7 +20,6 @@ comm_cpp cpp file _imports declarations = ("_comm.cpp", [lt| #include "#{file}_reflection.h" #include "#{file}_comm.h" -#include <bond/core/exception.h> #{CPP.openNamespace cpp} #{doubleLineSepEnd 1 statics declarations}
+ src/Language/Bond/Codegen/Cpp/Grpc_cpp.hs view
@@ -0,0 +1,33 @@+-- Copyright (c) Microsoft. All rights reserved. +-- Licensed under the MIT license. See LICENSE file in the project root for full license information. + +{-# LANGUAGE QuasiQuotes, OverloadedStrings, RecordWildCards #-} + +module Language.Bond.Codegen.Cpp.Grpc_cpp (grpc_cpp) where + +import Data.Monoid +import Prelude +import Data.Text.Lazy (Text) +import Text.Shakespeare.Text +import Language.Bond.Syntax.Types +import Language.Bond.Codegen.TypeMapping +import Language.Bond.Codegen.Util +import qualified Language.Bond.Codegen.Cpp.Util as CPP + +-- | Codegen template for generating /base_name/_grpc.cpp containing +-- definitions of helper functions and schema metadata static variables. +grpc_cpp :: MappingContext -> String -> [Import] -> [Declaration] -> (String, Text) +grpc_cpp cpp file _imports declarations = ("_grpc.cpp", [lt| +#include "#{file}_reflection.h" +#include "#{file}_grpc.h" + +#{CPP.openNamespace cpp} + #{doubleLineSepEnd 1 statics declarations} +#{CPP.closeNamespace cpp} +|]) + where + -- definitions of Schema statics for non-generic services + statics s@Service {..} = + if null declParams then CPP.schemaMetadata cpp s else mempty + + statics _ = mempty
src/Language/Bond/Codegen/Cpp/Grpc_h.hs view
@@ -11,6 +11,7 @@ import qualified Data.Text.Lazy as L import Data.Text.Lazy.Builder import Text.Shakespeare.Text +import Language.Bond.Util import Language.Bond.Syntax.Types import Language.Bond.Codegen.Util import Language.Bond.Codegen.TypeMapping @@ -20,7 +21,7 @@ -- | Codegen template for generating /base_name/_grpc.h containing declarations of -- of service interface and proxy. grpc_h :: Maybe String -> MappingContext -> String -> [Import] -> [Declaration] -> (String, L.Text) -grpc_h _ cpp file imports declarations = ("_grpc.h", [lt| +grpc_h export_attribute cpp file imports declarations = ("_grpc.h", [lt| #pragma once #include "#{file}_reflection.h" @@ -30,6 +31,7 @@ #include <bond/ext/grpc/bond_utils.h> #include <bond/ext/grpc/client_callback.h> #include <bond/ext/grpc/io_manager.h> +#include <bond/ext/grpc/reflection.h> #include <bond/ext/grpc/thread_pool.h> #include <bond/ext/grpc/unary_call.h> #include <bond/ext/grpc/detail/client_call_data.h> @@ -81,6 +83,8 @@ #{template}class #{declName} final { public: + struct Schema; + template <typename TThreadPool> class #{proxyName} { @@ -141,10 +145,68 @@ { } #{doubleLineSep 0 methodDecl serviceMethods} + +#{template}struct #{className}::Schema +{ + #{export_attr}static const ::bond::Metadata metadata; + + #{newlineSep 1 methodMetadata serviceMethods} + + public: struct service + { + #{doubleLineSep 2 methodTemplate serviceMethods} + }; + + private: typedef boost::mpl::list<> methods0; + #{newlineSep 1 pushMethod indexedMethods} + + public: typedef #{typename}methods#{length serviceMethods}::type methods; + + #{constructor} +}; +#{onlyTemplate $ CPP.schemaMetadata cpp s} |] where className = CPP.className s template = CPP.template s + onlyTemplate x = if null declParams then mempty else x + typename = onlyTemplate [lt|typename |] + + export_attr = optional (\a -> [lt|#{a} + |]) export_attribute + + methodMetadataVar m = [lt|s_#{methodName m}_metadata|] + + methodMetadata m = + [lt|private: #{export_attr}static const ::bond::Metadata #{methodMetadataVar m};|] + + -- reversed list of method names zipped with indexes + indexedMethods :: [(String, Int)] + indexedMethods = zipWith ((,) . methodName) (reverse serviceMethods) [0..] + + pushMethod (method, i) = + [lt|private: typedef #{typename}boost::mpl::push_front<methods#{i}, #{typename}service::#{method}>::type methods#{i + 1};|] + + -- constructor, generated only for service templates + constructor = onlyTemplate [lt|Schema() + { + // Force instantiation of template statics + (void)metadata; + #{newlineSep 3 static serviceMethods} + }|] + where + static m = [lt|(void)#{methodMetadataVar m};|] + + methodTemplate m = [lt|typedef ::bond::ext::gRPC::reflection::MethodTemplate< + #{className}, + #{bonded $ methodInput m}, + #{result m}, + &#{methodMetadataVar m} + > #{methodName m};|] + where + result Event{} = "void" + result Function{..} = bonded methodResult + proxyName = "ClientCore" :: String serviceName = "ServiceCore" :: String @@ -267,16 +329,16 @@ std::bind(&#{serviceName}::#{methodName}, this, std::placeholders::_1));|] queueReceive (index,Function{..}) = [lt|this->queue_receive( #{index}, - &#{serviceRdMember methodName}->_receivedCall->_context, - &#{serviceRdMember methodName}->_receivedCall->_request, - &#{serviceRdMember methodName}->_receivedCall->_responder, + &#{serviceRdMember methodName}->_receivedCall->context(), + &#{serviceRdMember methodName}->_receivedCall->request(), + &#{serviceRdMember methodName}->_receivedCall->responder(), #{cqParam}, &#{serviceRdMember methodName}.get());|] queueReceive (index,Event{..}) = [lt|this->queue_receive( #{index}, - &#{serviceRdMember methodName}->_receivedCall->_context, - &#{serviceRdMember methodName}->_receivedCall->_request, - &#{serviceRdMember methodName}->_receivedCall->_responder, + &#{serviceRdMember methodName}->_receivedCall->context(), + &#{serviceRdMember methodName}->_receivedCall->request(), + &#{serviceRdMember methodName}->_receivedCall->responder(), #{cqParam}, &#{serviceRdMember methodName}.get());|]
src/Language/Bond/Codegen/Cpp/Types_h.hs view
@@ -35,7 +35,7 @@ #{newlineBeginSep 0 includeHeader userHeaders} #include <bond/core/bond_version.h> -#if BOND_VERSION < 0x0520 +#if BOND_VERSION < 0x0700 #error This file was generated by a newer version of the Bond compiler and is incompatible with your version of the Bond library. #endif @@ -206,10 +206,23 @@ { }|] + needAlloc alloc = isJust structBase || any (allocParameterized alloc . fieldType) structFields + allocParameterized alloc t = (isStruct t) || (L.isInfixOf (L.pack alloc) . toLazyText $ cppType t) + -- default constructor defaultCtor = [lt| - #{declName}()#{initList}#{ctorBody}|] + #{dummyTemplateTag}#{declName}(#{vc12WorkaroundParam})#{initList}#{ctorBody}|] where + needAllocParam = maybe False needAlloc allocator + + vc12WorkaroundParam = if needAllocParam then [lt|_bond_vc12_ctor_workaround_ = {}|] else mempty + + dummyTemplateTag = if needAllocParam + then [lt|struct _bond_vc12_ctor_workaround_ {}; + template <int = 0> // Workaround to avoid compilation if not used + |] + else mempty + initList = initializeList mempty $ commaLineSep 3 fieldInit structFields fieldInit Field {..} = optional (\x -> [lt|#{fieldName}(#{x})|]) @@ -220,9 +233,7 @@ #{declName}(const #{alloc}&#{allocParam})#{initList}#{ctorBody} |] where - allocParam = if needAlloc then [lt| allocator|] else mempty - where - needAlloc = isJust structBase || any (allocParameterized . fieldType) structFields + allocParam = if needAlloc alloc then [lt| allocator|] else mempty initList = initializeList (optional baseInit structBase) (commaLineSep 3 fieldInit structFields) @@ -230,7 +241,7 @@ fieldInit Field {..} = optional (\x -> [lt|#{fieldName}(#{x})|]) $ allocInitValue fieldType fieldDefault allocInitValue t@(BT_UserDefined a@Alias {} args) d - | allocParameterized t = allocInitValue (resolveAlias a args) d + | allocParameterized alloc t = allocInitValue (resolveAlias a args) d | otherwise = initValue t d allocInitValue (BT_Nullable t) _ = allocInitValue t Nothing allocInitValue (BT_Maybe t) _ = allocInitValue t Nothing @@ -244,7 +255,6 @@ keyType (BT_Map key _) = cppType key keyType (BT_UserDefined a@Alias {} args) = keyType $ resolveAlias a args keyType _ = error "allocatorCtor/keyType: impossible happened." - allocParameterized t = (isStruct t) || (L.isInfixOf (L.pack alloc) . toLazyText $ cppType t) -- copy constructor copyCtor = if hasMetaFields then define else implicitlyDeclared
src/Language/Bond/Codegen/Cs/Comm_cs.hs view
@@ -43,6 +43,8 @@ #{CS.disableReSharperWarnings} namespace #{csNamespace} { + using System.Collections.Generic; + #{doubleLineSep 1 comm declarations} } // #{csNamespace} |]) @@ -57,12 +59,12 @@ where generics = angles $ sepBy ", " paramName declParams - methodDeclaration Function{..} = [lt|global::System.Threading.Tasks.Task<global::Bond.Comm.IMessage<#{getMessageResultTypeName}>> #{methodName}Async(global::Bond.Comm.IMessage<#{getMessageInputTypeName}> param, global::System.Threading.CancellationToken ct);|] + methodDeclaration Function{..} = [lt|#{CS.schemaAttributes 2 methodAttributes}global::System.Threading.Tasks.Task<global::Bond.Comm.IMessage<#{getMessageResultTypeName}>> #{methodName}Async(global::Bond.Comm.IMessage<#{getMessageInputTypeName}> param, global::System.Threading.CancellationToken ct);|] where getMessageResultTypeName = getMessageTypeName cs methodResult getMessageInputTypeName = getMessageTypeName cs methodInput - methodDeclaration Event{..} = [lt|void #{methodName}Async(global::Bond.Comm.IMessage<#{getMessageInputTypeName}> param);|] + methodDeclaration Event{..} = [lt|#{CS.schemaAttributes 2 methodAttributes}void #{methodName}Async(global::Bond.Comm.IMessage<#{getMessageInputTypeName}> param);|] where getMessageInputTypeName = getMessageTypeName cs methodInput @@ -74,6 +76,8 @@ #{CS.disableReSharperWarnings} namespace #{csNamespace} { + using System.Collections.Generic; + #{doubleLineSep 1 comm declarations} } // #{csNamespace} |]) @@ -103,7 +107,7 @@ interfaceGenerics = angles $ sepBy "," paramName declParams -- of the form "<T1, T2, T3>" proxyGenerics = sepEndBy ", " paramName declParams -- of the form "T1, T2, T3, " - proxyMethod Function{..} = [lt|public global::System.Threading.Tasks.Task<global::Bond.Comm.IMessage<#{getMessageResultTypeName}>> #{methodName}Async(#{getMessageProxyInputParam cs methodInput}) + proxyMethod Function{..} = [lt|#{CS.schemaAttributes 2 methodAttributes}public global::System.Threading.Tasks.Task<global::Bond.Comm.IMessage<#{getMessageResultTypeName}>> #{methodName}Async(#{getMessageProxyInputParam cs methodInput}) { var message = new global::Bond.Comm.Message<#{getMessageInputTypeName}>(#{paramOrBondVoid methodInput}); return #{methodName}Async(message, global::System.Threading.CancellationToken.None); @@ -121,7 +125,7 @@ getMessageResultTypeName = getMessageTypeName cs methodResult getMessageInputTypeName = getMessageTypeName cs methodInput - proxyMethod Event{..} = [lt|public void #{methodName}Async(#{getMessageProxyInputParam cs methodInput}) + proxyMethod Event{..} = [lt|#{CS.schemaAttributes 2 methodAttributes}public void #{methodName}Async(#{getMessageProxyInputParam cs methodInput}) { var message = new global::Bond.Comm.Message<#{getMessageInputTypeName}>(#{paramOrBondVoid methodInput}); #{methodName}Async(message); @@ -145,6 +149,8 @@ #{CS.disableReSharperWarnings} namespace #{csNamespace} { + using System.Collections.Generic; + #{doubleLineSep 1 comm declarations} } // #{csNamespace} |]) @@ -173,7 +179,7 @@ methodInfo Function{..} = [lt|yield return new global::Bond.Comm.ServiceMethodInfo {MethodName="#{getDeclTypeName idl s}.#{methodName}", Callback = #{methodName}Async_Glue, CallbackType = global::Bond.Comm.ServiceCallbackType.RequestResponse};|] methodInfo Event{..} = [lt|yield return new global::Bond.Comm.ServiceMethodInfo {MethodName="#{getDeclTypeName idl s}.#{methodName}", Callback = #{methodName}Async_Glue, CallbackType = global::Bond.Comm.ServiceCallbackType.Event};|] - methodAbstract Function{..} = [lt|public abstract global::System.Threading.Tasks.Task<global::Bond.Comm.IMessage<#{getMessageResultTypeName}>> #{methodName}Async(global::Bond.Comm.IMessage<#{getMessageInputTypeName}> param, global::System.Threading.CancellationToken ct);|] + methodAbstract Function{..} = [lt|#{CS.schemaAttributes 2 methodAttributes}public abstract global::System.Threading.Tasks.Task<global::Bond.Comm.IMessage<#{getMessageResultTypeName}>> #{methodName}Async(global::Bond.Comm.IMessage<#{getMessageInputTypeName}> param, global::System.Threading.CancellationToken ct);|] where getMessageResultTypeName = getMessageTypeName cs methodResult getMessageInputTypeName = getMessageTypeName cs methodInput @@ -192,7 +198,7 @@ getMessageResultTypeName = getMessageTypeName cs methodResult getMessageInputTypeName = getMessageTypeName cs methodInput - methodGlue Event{..} = [lt|private global::System.Threading.Tasks.Task #{methodName}Async_Glue(global::Bond.Comm.IMessage param, global::Bond.Comm.ReceiveContext context, global::System.Threading.CancellationToken ct) + methodGlue Event{..} = [lt|#{CS.schemaAttributes 2 methodAttributes}private global::System.Threading.Tasks.Task #{methodName}Async_Glue(global::Bond.Comm.IMessage param, global::Bond.Comm.ReceiveContext context, global::System.Threading.CancellationToken ct) { #{methodName}Async(param.Convert<#{getMessageInputTypeName}>()); return global::Bond.Comm.CodegenHelpers.CompletedTask;
src/Language/Bond/Codegen/Cs/Grpc_cs.hs view
@@ -28,6 +28,8 @@ namespace #{csNamespace} { + using System.Collections.Generic; + #{doubleLineSep 1 grpc declarations} } // #{csNamespace} |]) @@ -103,9 +105,9 @@ global::Bond.Grpc.Marshaller<#{getMessageTypeName methodInput}>.Instance, global::Bond.Grpc.Marshaller<#{getMessageTypeName Nothing}>.Instance);|] - serverBaseMethods Function{..} = [lt|public abstract global::System.Threading.Tasks.Task<global::Bond.Grpc.IMessage<#{getMessageTypeName methodResult}>> #{methodName}(global::Bond.Grpc.IMessage<#{getMessageTypeName methodInput}> request, global::Grpc.Core.ServerCallContext context);|] + serverBaseMethods Function{..} = [lt|#{CS.schemaAttributes 3 methodAttributes}public abstract global::System.Threading.Tasks.Task<global::Bond.Grpc.IMessage<#{getMessageTypeName methodResult}>> #{methodName}(global::Bond.Grpc.IMessage<#{getMessageTypeName methodInput}> request, global::Grpc.Core.ServerCallContext context);|] - serverBaseMethods Event{..} = [lt|public abstract global::System.Threading.Tasks.Task #{methodName}(global::Bond.Grpc.IMessage<#{getMessageTypeName methodInput}> request, global::Grpc.Core.ServerCallContext context); + serverBaseMethods Event{..} = [lt|#{CS.schemaAttributes 3 methodAttributes}public abstract global::System.Threading.Tasks.Task #{methodName}(global::Bond.Grpc.IMessage<#{getMessageTypeName methodInput}> request, global::Grpc.Core.ServerCallContext context); internal global::System.Threading.Tasks.Task<global::Bond.Grpc.IMessage<#{getMessageTypeName Nothing}>> #{uniqImplName methodName}(global::Bond.Grpc.IMessage<#{getMessageTypeName methodInput}> request, global::Grpc.Core.ServerCallContext context) { return global::Bond.Grpc.Internal.NothingCallHandler.Handle(#{methodName}, request, context); @@ -117,7 +119,7 @@ requestOrVoidConstructor Nothing = [lt|global::Bond.Grpc.Message.Void|] requestOrVoidConstructor _ = [lt|global::Bond.Grpc.Message.From(request)|] - clientMethods Function{..} = [lt|public virtual global::Grpc.Core.AsyncUnaryCall<global::Bond.Grpc.IMessage<#{getMessageTypeName methodResult}>> #{methodName}Async(#{firstParam methodInput}global::Grpc.Core.Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) + clientMethods Function{..} = [lt|#{CS.schemaAttributes 3 methodAttributes}public virtual global::Grpc.Core.AsyncUnaryCall<global::Bond.Grpc.IMessage<#{getMessageTypeName methodResult}>> #{methodName}Async(#{firstParam methodInput}global::Grpc.Core.Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) { var message = #{requestOrVoidConstructor methodInput}; return #{methodName}Async(message, new global::Grpc.Core.CallOptions(headers, deadline, cancellationToken)); @@ -128,7 +130,7 @@ return CallInvoker.AsyncUnaryCall(Method_#{methodName}, null, options, request); }|] - clientMethods Event{..} = [lt|public virtual void #{methodName}Async(#{firstParam methodInput}global::Grpc.Core.Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) + clientMethods Event{..} = [lt|#{CS.schemaAttributes 3 methodAttributes}public virtual void #{methodName}Async(#{firstParam methodInput}global::Grpc.Core.Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) { var message = #{requestOrVoidConstructor methodInput}; #{methodName}Async(message, new global::Grpc.Core.CallOptions(headers, deadline, cancellationToken));
src/Language/Bond/Codegen/Cs/Util.hs view
@@ -75,7 +75,9 @@ <> generatedCodeAttr -- C# service attributes -typeAttributes _ Service {..} = generatedCodeAttr +typeAttributes cs s@Service {..} = + optionalTypeAttributes cs s + <> generatedCodeAttr typeAttributes _ _ = error "typeAttributes: impossible happened."
src/Language/Bond/Codegen/Templates.hs view
@@ -45,6 +45,7 @@ , comm_h , comm_cpp , grpc_h + , grpc_cpp -- ** C# , FieldMapping(..) , StructMapping(..) @@ -65,6 +66,7 @@ import Language.Bond.Codegen.Cpp.Types_h import Language.Bond.Codegen.Cpp.Comm_cpp import Language.Bond.Codegen.Cpp.Comm_h +import Language.Bond.Codegen.Cpp.Grpc_cpp import Language.Bond.Codegen.Cpp.Grpc_h import Language.Bond.Codegen.Cs.Types_cs import Language.Bond.Codegen.Cs.Comm_cs
src/Language/Bond/Codegen/TypeMapping.hs view
@@ -365,8 +365,8 @@ -- C++ type mapping with custom allocator cppTypeCustomAlloc :: Builder -> Type -> TypeNameBuilder -cppTypeCustomAlloc alloc BT_String = pure $ "std::basic_string<char, std::char_traits<char>, typename " <> alloc <> "::rebind<char>::other>" -cppTypeCustomAlloc alloc BT_WString = pure $ "std::basic_string<wchar_t, std::char_traits<wchar_t>, typename " <> alloc <> "::rebind<wchar_t>::other>" +cppTypeCustomAlloc alloc BT_String = pure $ "std::basic_string<char, std::char_traits<char>, typename std::allocator_traits<" <> alloc <> ">::template rebind_alloc<char> >" +cppTypeCustomAlloc alloc BT_WString = pure $ "std::basic_string<wchar_t, std::char_traits<wchar_t>, typename std::allocator_traits<" <> alloc <> ">::template rebind_alloc<wchar_t> >" cppTypeCustomAlloc alloc BT_MetaName = cppTypeCustomAlloc alloc BT_String cppTypeCustomAlloc alloc BT_MetaFullName = cppTypeCustomAlloc alloc BT_String cppTypeCustomAlloc alloc (BT_List element) = "std::list<" <>> elementTypeName element <<>> ", " <>> allocator alloc element <<> ">" @@ -382,11 +382,11 @@ allocator :: Builder -> Type -> TypeNameBuilder allocator alloc element = - "typename " <>> alloc <>> "::rebind<" <>> elementTypeName element <<> ">::other" + "typename std::allocator_traits<" <>> alloc <>> ">::template rebind_alloc<" <>> elementTypeName element <<> ">" pairAllocator :: Builder -> Type -> Type -> TypeNameBuilder pairAllocator alloc key value = - "typename " <>> alloc <>> "::rebind<" <>> "std::pair<const " <>> elementTypeName key <<>> ", " <>> elementTypeName value <<> "> >::other" + "typename std::allocator_traits<" <>> alloc <>> ">::template rebind_alloc<" <>> "std::pair<const " <>> elementTypeName key <<>> ", " <>> elementTypeName value <<> "> >" cppSyntaxFix :: Builder -> Builder cppSyntaxFix = fromLazyText . snd . L.foldr fixInvalid (' ', mempty) . toLazyText
tests/TestMain.hs view
@@ -171,6 +171,10 @@ [ "c#" ] "generic_service" + , verifyCsCommCodegen + [ "c#" + ] + "service_attributes" ] ] ]
tests/Tests/Codegen.hs view
@@ -96,6 +96,7 @@ options = processOptions args templates = [ grpc_h (export_attribute options) + , grpc_cpp , types_cpp ]