diff --git a/src/command_line.cc b/src/command_line.cc index 25ce4846..fd624692 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -92,36 +92,6 @@ std::string Join(const std::vector& elements, std::string sep) { return result; } -struct Ipc_Quit : public IpcMessage { - static constexpr IpcId kIpcId = IpcId::Quit; -}; -template -void Reflect(TVisitor& visitor, Ipc_Quit& value) {} - -struct Ipc_IsAlive : public IpcMessage { - static constexpr IpcId kIpcId = IpcId::IsAlive; -}; -template -void Reflect(TVisitor& visitor, Ipc_IsAlive& value) {} - -struct Ipc_OpenProject : public IpcMessage { - static constexpr IpcId kIpcId = IpcId::OpenProject; - std::string project_path; -}; -template -void Reflect(TVisitor& visitor, Ipc_OpenProject& value) { - Reflect(visitor, value.project_path); -} - -struct Ipc_Cout : public IpcMessage { - static constexpr IpcId kIpcId = IpcId::Cout; - std::string content; -}; -template -void Reflect(TVisitor& visitor, Ipc_Cout& value) { - Reflect(visitor, value.content); -} - template void SendOutMessageToClient(IpcMessageQueue* queue, T& response) { std::ostringstream sstream; @@ -132,8 +102,6 @@ void SendOutMessageToClient(IpcMessageQueue* queue, T& response) { queue->SendMessage(&queue->for_client, Ipc_Cout::kIpcId, out); } - - template void RegisterId(IpcMessageQueue* t) { t->RegisterId(T::kIpcId, @@ -767,7 +735,7 @@ int main(int argc, char** argv) { if (context.shouldExit()) return res; - //RunTests(); + RunTests(); return 0; } else if (options.find("--help") != options.end()) { diff --git a/src/ipc.cc b/src/ipc.cc new file mode 100644 index 00000000..a30b69d0 --- /dev/null +++ b/src/ipc.cc @@ -0,0 +1,28 @@ +#include "ipc.h" + +#include + +const char* IpcIdToString(IpcId id) { + switch (id) { + case IpcId::CancelRequest: + return "$/cancelRequest"; + case IpcId::Initialize: + return "initialize"; + case IpcId::Initialized: + return "initialized"; + case IpcId::TextDocumentDocumentSymbol: + return "textDocument/documentSymbol"; + case IpcId::TextDocumentCodeLens: + return "textDocument/codeLens"; + case IpcId::CodeLensResolve: + return "codeLens/resolve"; + case IpcId::WorkspaceSymbol: + return "workspace/symbol"; + default: + assert(false); + exit(1); + } +} + +BaseIpcMessage::BaseIpcMessage(IpcId method_id) + : method_id(method_id) {} diff --git a/src/ipc.h b/src/ipc.h new file mode 100644 index 00000000..73dc808d --- /dev/null +++ b/src/ipc.h @@ -0,0 +1,58 @@ +#pragma once + +#include "utils.h" +#include "serializer.h" + +#include + +enum class IpcId : int { + // Language server specific requests. + CancelRequest = 0, + Initialize, + Initialized, + TextDocumentDocumentSymbol, + TextDocumentCodeLens, + CodeLensResolve, + WorkspaceSymbol, + + // Internal implementation detail. + Quit, + IsAlive, + OpenProject, + Cout +}; +MAKE_ENUM_HASHABLE(IpcId) +MAKE_REFLECT_TYPE_PROXY(IpcId, int) +const char* IpcIdToString(IpcId id); + +struct BaseIpcMessage { + const IpcId method_id; + BaseIpcMessage(IpcId method_id); +}; + +template +struct IpcMessage : public BaseIpcMessage { + IpcMessage() : BaseIpcMessage(T::kIpcId) {} +}; + +struct Ipc_Quit : public IpcMessage { + static constexpr IpcId kIpcId = IpcId::Quit; +}; +MAKE_REFLECT_EMPTY_STRUCT(Ipc_Quit); + +struct Ipc_IsAlive : public IpcMessage { + static constexpr IpcId kIpcId = IpcId::IsAlive; +}; +MAKE_REFLECT_EMPTY_STRUCT(Ipc_IsAlive); + +struct Ipc_OpenProject : public IpcMessage { + static constexpr IpcId kIpcId = IpcId::OpenProject; + std::string project_path; +}; +MAKE_REFLECT_STRUCT(Ipc_OpenProject, project_path); + +struct Ipc_Cout : public IpcMessage { + static constexpr IpcId kIpcId = IpcId::Cout; + std::string content; +}; +MAKE_REFLECT_STRUCT(Ipc_Cout, content); \ No newline at end of file diff --git a/src/language_server_api.cc b/src/language_server_api.cc index 80346d1a..582d8dca 100644 --- a/src/language_server_api.cc +++ b/src/language_server_api.cc @@ -1,27 +1,5 @@ #include "language_server_api.h" -const char* IpcIdToString(IpcId id) { - switch (id) { - case IpcId::CancelRequest: - return "$/cancelRequest"; - case IpcId::Initialize: - return "initialize"; - case IpcId::Initialized: - return "initialized"; - case IpcId::TextDocumentDocumentSymbol: - return "textDocument/documentSymbol"; - case IpcId::TextDocumentCodeLens: - return "textDocument/codeLens"; - case IpcId::CodeLensResolve: - return "codeLens/resolve"; - case IpcId::WorkspaceSymbol: - return "workspace/symbol"; - default: - assert(false); - exit(1); - } -} - void Reflect(Writer& visitor, lsRequestId& value) { assert(value.id0.has_value() || value.id1.has_value()); @@ -111,9 +89,6 @@ MessageRegistry* MessageRegistry::instance() { return instance_; } -BaseIpcMessage::BaseIpcMessage(IpcId method_id) - : method_id(method_id) {} - void lsResponseError::Write(Writer& visitor) { auto& value = *this; int code = static_cast(this->code); diff --git a/src/language_server_api.h b/src/language_server_api.h index 0e0be07c..c9b8775a 100644 --- a/src/language_server_api.h +++ b/src/language_server_api.h @@ -1,5 +1,6 @@ #pragma once +#include "ipc.h" #include "serializer.h" #include "utils.h" @@ -22,25 +23,6 @@ using std::experimental::nullopt; ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// -enum class IpcId : int { - // Language server specific requests. - CancelRequest = 0, - Initialize, - Initialized, - TextDocumentDocumentSymbol, - TextDocumentCodeLens, - CodeLensResolve, - WorkspaceSymbol, - - // Internal implementation detail. - Quit, - IsAlive, - OpenProject, - Cout -}; -MAKE_ENUM_HASHABLE(IpcId) -MAKE_REFLECT_TYPE_PROXY(IpcId, int) -const char* IpcIdToString(IpcId id); struct lsRequestId { optional id0; @@ -99,8 +81,6 @@ void Reflect(Reader& visitor, lsRequestId& id); ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// -struct BaseIpcMessage; - struct MessageRegistry { static MessageRegistry* instance_; static MessageRegistry* instance(); @@ -123,15 +103,6 @@ struct MessageRegistry { }; -struct BaseIpcMessage { - const IpcId method_id; - BaseIpcMessage(IpcId method_id); -}; - -template -struct IpcMessage : public BaseIpcMessage { - IpcMessage() : BaseIpcMessage(T::kIpcId) {} -}; template struct lsOutMessage { @@ -152,8 +123,6 @@ struct lsOutMessage { } }; - - struct lsResponseError { struct Data { virtual void Write(Writer& writer) = 0; @@ -241,7 +210,7 @@ struct lsDocumentUri { lsDocumentUri(); bool operator==(const lsDocumentUri& other) const; - + void SetPath(const std::string& path); std::string GetPath(); @@ -266,14 +235,7 @@ struct lsPosition { int character = 0; }; MAKE_HASHABLE(lsPosition, t.line, t.character); -template -void Reflect(TVisitor& visitor, lsPosition& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(line); - REFLECT_MEMBER(character); - REFLECT_MEMBER_END(); -} - +MAKE_REFLECT_STRUCT(lsPosition, line, character); struct lsRange { lsRange(); @@ -285,15 +247,7 @@ struct lsRange { lsPosition end; }; MAKE_HASHABLE(lsRange, t.start, t.end); - -template -void Reflect(TVisitor& visitor, lsRange& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(start); - REFLECT_MEMBER(end); - REFLECT_MEMBER_END(); -} - +MAKE_REFLECT_STRUCT(lsRange, start, end); struct lsLocation { lsLocation(); @@ -304,15 +258,8 @@ struct lsLocation { lsDocumentUri uri; lsRange range; }; -MAKE_HASHABLE(lsLocation, t.uri, t.range) -template -void Reflect(TVisitor& visitor, lsLocation& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(uri); - REFLECT_MEMBER(range); - REFLECT_MEMBER_END(); -} - +MAKE_HASHABLE(lsLocation, t.uri, t.range); +MAKE_REFLECT_STRUCT(lsLocation, uri, range); enum class lsSymbolKind : int { File = 1, @@ -334,7 +281,7 @@ enum class lsSymbolKind : int { Boolean = 17, Array = 18 }; -MAKE_REFLECT_TYPE_PROXY(lsSymbolKind, int) +MAKE_REFLECT_TYPE_PROXY(lsSymbolKind, int); struct lsSymbolInformation { std::string name; @@ -342,16 +289,7 @@ struct lsSymbolInformation { lsLocation location; std::string containerName; }; - -template -void Reflect(TVisitor& visitor, lsSymbolInformation& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(name); - REFLECT_MEMBER(kind); - REFLECT_MEMBER(location); - REFLECT_MEMBER(containerName); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(lsSymbolInformation, name, kind, location, containerName); template struct lsCommand { @@ -362,7 +300,6 @@ struct lsCommand { // Arguments to run the command with. T arguments; }; - template void Reflect(TVisitor& visitor, lsCommand& value) { REFLECT_MEMBER_START(); @@ -383,7 +320,6 @@ struct lsCodeLens { // a code lens and a code lens resolve request. TData data; }; - template void Reflect(TVisitor& visitor, lsCodeLens& value) { REFLECT_MEMBER_START(); @@ -399,13 +335,7 @@ void Reflect(TVisitor& visitor, lsCodeLens& value) { struct lsTextDocumentIdentifier { lsDocumentUri uri; }; - -template -void Reflect(TVisitor& visitor, lsTextDocumentIdentifier& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(uri); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(lsTextDocumentIdentifier, uri); // TODO: TextDocumentItem // TODO: VersionedTextDocumentIdentifier @@ -550,31 +480,16 @@ struct lsWorkspaceClientCapabilites { optional executeCommand; }; -template -void Reflect(TVisitor& visitor, lsWorkspaceClientCapabilites::lsWorkspaceEdit& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(documentChanges); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites::lsWorkspaceEdit, documentChanges); +MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites::lsGenericDynamicReg, dynamicRegistration); +MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites, + applyEdit, + workspaceEdit, + didChangeConfiguration, + didChangeWatchedFiles, + symbol, + executeCommand); -template -void Reflect(TVisitor& visitor, lsWorkspaceClientCapabilites::lsGenericDynamicReg& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(dynamicRegistration); - REFLECT_MEMBER_END(); -} - -template -void Reflect(TVisitor& visitor, lsWorkspaceClientCapabilites& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(applyEdit); - REFLECT_MEMBER(workspaceEdit); - REFLECT_MEMBER(didChangeConfiguration); - REFLECT_MEMBER(didChangeWatchedFiles); - REFLECT_MEMBER(symbol); - REFLECT_MEMBER(executeCommand); - REFLECT_MEMBER_END(); -} // Text document specific client capabilities. @@ -668,66 +583,27 @@ struct lsTextDocumentClientCapabilities { optional rename; }; -template -void Reflect(TVisitor& visitor, lsTextDocumentClientCapabilities::lsSynchronization& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(dynamicRegistration); - REFLECT_MEMBER(willSave); - REFLECT_MEMBER(willSaveWaitUntil); - REFLECT_MEMBER(didSave); - REFLECT_MEMBER_END(); -} - -template -void Reflect(TVisitor& visitor, lsTextDocumentClientCapabilities::lsCompletion& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(dynamicRegistration); - REFLECT_MEMBER(completionItem); - REFLECT_MEMBER_END(); -} - -template -void Reflect(TVisitor& visitor, lsTextDocumentClientCapabilities::lsCompletion::lsCompletionItem& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(snippetSupport); - REFLECT_MEMBER_END(); -} - -template -void Reflect(TVisitor& visitor, lsTextDocumentClientCapabilities::lsGenericDynamicReg& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(dynamicRegistration); - REFLECT_MEMBER_END(); -} - -template -void Reflect(TVisitor& visitor, lsTextDocumentClientCapabilities::CodeLensRegistrationOptions& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(dynamicRegistration); - REFLECT_MEMBER(resolveProvider); - REFLECT_MEMBER_END(); -} - -template -void Reflect(TVisitor& visitor, lsTextDocumentClientCapabilities& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(synchronization); - REFLECT_MEMBER(completion); - REFLECT_MEMBER(hover); - REFLECT_MEMBER(signatureHelp); - REFLECT_MEMBER(references); - REFLECT_MEMBER(documentHighlight); - REFLECT_MEMBER(documentSymbol); - REFLECT_MEMBER(formatting); - REFLECT_MEMBER(rangeFormatting); - REFLECT_MEMBER(onTypeFormatting); - REFLECT_MEMBER(definition); - REFLECT_MEMBER(codeAction); - REFLECT_MEMBER(codeLens); - REFLECT_MEMBER(documentLink); - REFLECT_MEMBER(rename); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsSynchronization, dynamicRegistration, willSave, willSaveWaitUntil, didSave); +MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsCompletion, dynamicRegistration, completionItem); +MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsCompletion::lsCompletionItem, snippetSupport); +MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsGenericDynamicReg, dynamicRegistration); +MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::CodeLensRegistrationOptions, dynamicRegistration, resolveProvider); +MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities, + synchronization, + completion, + hover, + signatureHelp, + references, + documentHighlight, + documentSymbol, + formatting, + rangeFormatting, + onTypeFormatting, + definition, + codeAction, + codeLens, + documentLink, + rename); struct lsClientCapabilities { // Workspace specific client capabilities. @@ -741,14 +617,7 @@ struct lsClientCapabilities { */ // experimental?: any; // TODO }; - -template -void Reflect(TVisitor& visitor, lsClientCapabilities& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(workspace); - REFLECT_MEMBER(textDocument); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(lsClientCapabilities, workspace, textDocument); struct lsInitializeParams { // The process Id of the parent process that started @@ -785,17 +654,7 @@ struct lsInitializeParams { }; void Reflect(Reader& reader, lsInitializeParams::lsTrace& value); void Reflect(Writer& writer, lsInitializeParams::lsTrace& value); - -template -void Reflect(TVisitor& visitor, lsInitializeParams& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(processId); - REFLECT_MEMBER(rootPath); - REFLECT_MEMBER(rootUri); - REFLECT_MEMBER(capabilities); - REFLECT_MEMBER(trace); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(lsInitializeParams, processId, rootPath, rootUri, capabilities, trace); struct lsInitializeError { @@ -804,13 +663,7 @@ struct lsInitializeError { // in the ResponseError. bool retry; }; - -template -void Reflect(TVisitor& visitor, lsInitializeError& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(retry); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(lsInitializeError, retry); // Defines how the host (editor) should sync document changes to the language server. enum class lsTextDocumentSyncKind { @@ -837,40 +690,21 @@ struct lsCompletionOptions { // The characters that trigger completion automatically. std::vector triggerCharacters; }; - -template -void Reflect(TVisitor& visitor, lsCompletionOptions& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(resolveProvider); - REFLECT_MEMBER(triggerCharacters); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(lsCompletionOptions, resolveProvider, triggerCharacters); // Signature help options. struct lsSignatureHelpOptions { // The characters that trigger signature help automatically. std::vector triggerCharacters; }; - -template -void Reflect(TVisitor& visitor, lsSignatureHelpOptions& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(triggerCharacters); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(lsSignatureHelpOptions, triggerCharacters); // Code Lens options. struct lsCodeLensOptions { // Code lens has a resolve provider as well. bool resolveProvider = false; }; - -template -void Reflect(TVisitor& visitor, lsCodeLensOptions& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(resolveProvider); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(lsCodeLensOptions, resolveProvider); // Format document on type options struct lsDocumentOnTypeFormattingOptions { @@ -880,53 +714,28 @@ struct lsDocumentOnTypeFormattingOptions { // More trigger characters. std::vector moreTriggerCharacter; }; - -template -void Reflect(TVisitor& visitor, lsDocumentOnTypeFormattingOptions& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(firstTriggerCharacter); - REFLECT_MEMBER(moreTriggerCharacter); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(lsDocumentOnTypeFormattingOptions, firstTriggerCharacter, moreTriggerCharacter); // Document link options struct lsDocumentLinkOptions { // Document links have a resolve provider as well. bool resolveProvider = false; }; - -template -void Reflect(TVisitor& visitor, lsDocumentLinkOptions& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(resolveProvider); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(lsDocumentLinkOptions, resolveProvider); // Execute command options. struct lsExecuteCommandOptions { // The commands to be executed on the server std::vector commands; }; - -template -void Reflect(TVisitor& visitor, lsExecuteCommandOptions& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(commands); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(lsExecuteCommandOptions, commands); // Save options. struct lsSaveOptions { // The client is supposed to include the content on save. bool includeText = false; }; - -template -void Reflect(TVisitor& visitor, lsSaveOptions& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(includeText); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(lsSaveOptions, includeText); struct lsTextDocumentSyncOptions { // Open and close notifications are sent to the server. @@ -941,17 +750,7 @@ struct lsTextDocumentSyncOptions { // Save notifications are sent to the server. optional save; }; - -template -void Reflect(TVisitor& visitor, lsTextDocumentSyncOptions& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(openClose); - REFLECT_MEMBER(change); - REFLECT_MEMBER(willSave); - REFLECT_MEMBER(willSaveWaitUntil); - REFLECT_MEMBER(save); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(lsTextDocumentSyncOptions, openClose, change, willSave, willSaveWaitUntil, save); struct lsServerCapabilities { // Defines how text documents are synced. Is either a detailed structure defining each notification or @@ -990,42 +789,30 @@ struct lsServerCapabilities { // The server provides execute command support. optional executeCommandProvider; }; - -template -void Reflect(TVisitor& visitor, lsServerCapabilities& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(textDocumentSync); - REFLECT_MEMBER(hoverProvider); - REFLECT_MEMBER(completionProvider); - REFLECT_MEMBER(signatureHelpProvider); - REFLECT_MEMBER(definitionProvider); - REFLECT_MEMBER(referencesProvider); - REFLECT_MEMBER(documentHighlightProvider); - REFLECT_MEMBER(documentSymbolProvider); - REFLECT_MEMBER(workspaceSymbolProvider); - REFLECT_MEMBER(codeActionProvider); - REFLECT_MEMBER(codeLensProvider); - REFLECT_MEMBER(documentFormattingProvider); - REFLECT_MEMBER(documentRangeFormattingProvider); - REFLECT_MEMBER(documentOnTypeFormattingProvider); - REFLECT_MEMBER(renameProvider); - REFLECT_MEMBER(documentLinkProvider); - REFLECT_MEMBER(executeCommandProvider); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(lsServerCapabilities, + textDocumentSync, + hoverProvider, + completionProvider, + signatureHelpProvider, + definitionProvider, + referencesProvider, + documentHighlightProvider, + documentSymbolProvider, + workspaceSymbolProvider, + codeActionProvider, + codeLensProvider, + documentFormattingProvider, + documentRangeFormattingProvider, + documentOnTypeFormattingProvider, + renameProvider, + documentLinkProvider, + executeCommandProvider); struct lsInitializeResult { // The capabilities the language server provides. lsServerCapabilities capabilities; }; - -template -void Reflect(TVisitor& visitor, lsInitializeResult& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(capabilities); - REFLECT_MEMBER_END(); -} - +MAKE_REFLECT_STRUCT(lsInitializeResult, capabilities); struct Ipc_InitializeRequest : public IpcMessage { const static IpcId kIpcId = IpcId::Initialize; @@ -1033,38 +820,20 @@ struct Ipc_InitializeRequest : public IpcMessage { lsRequestId id; lsInitializeParams params; }; -template -void Reflect(TVisitor& visitor, Ipc_InitializeRequest& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(id); - REFLECT_MEMBER(params); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(Ipc_InitializeRequest, id, params); struct Out_InitializeResponse : public lsOutMessage { lsRequestId id; lsInitializeResult result; }; -template -void Reflect(TVisitor& visitor, Out_InitializeResponse& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(jsonrpc); - REFLECT_MEMBER(id); - REFLECT_MEMBER(result); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(Out_InitializeResponse, jsonrpc, id, result); struct Ipc_InitializedNotification : public IpcMessage { const static IpcId kIpcId = IpcId::Initialized; lsRequestId id; }; -template -void Reflect(TVisitor& visitor, Ipc_InitializedNotification& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(id); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(Ipc_InitializedNotification, id); @@ -1112,65 +881,33 @@ struct Ipc_CancelRequest : public IpcMessage { static const IpcId kIpcId = IpcId::CancelRequest; lsRequestId id; }; -template -void Reflect(TVisitor& visitor, Ipc_CancelRequest& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(id); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(Ipc_CancelRequest, id); // List symbols in a document. struct lsDocumentSymbolParams { lsTextDocumentIdentifier textDocument; }; -template -void Reflect(TVisitor& visitor, lsDocumentSymbolParams& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(textDocument); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(lsDocumentSymbolParams, textDocument); struct Ipc_TextDocumentDocumentSymbol : public IpcMessage { const static IpcId kIpcId = IpcId::TextDocumentDocumentSymbol; lsRequestId id; lsDocumentSymbolParams params; }; -template -void Reflect(TVisitor& visitor, Ipc_TextDocumentDocumentSymbol& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(id); - REFLECT_MEMBER(params); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(Ipc_TextDocumentDocumentSymbol, id, params); struct Out_TextDocumentDocumentSymbol : public lsOutMessage { lsRequestId id; std::vector result; }; -template -void Reflect(TVisitor& visitor, Out_TextDocumentDocumentSymbol& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(jsonrpc); - REFLECT_MEMBER(id); - REFLECT_MEMBER(result); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(Out_TextDocumentDocumentSymbol, jsonrpc, id, result); // List code lens in a document. struct lsDocumentCodeLensParams { lsTextDocumentIdentifier textDocument; }; -template -void Reflect(TVisitor& visitor, lsDocumentCodeLensParams& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(textDocument); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(lsDocumentCodeLensParams, textDocument); struct lsCodeLensUserData {}; -template -void Reflect(TVisitor& visitor, lsCodeLensUserData& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_EMPTY_STRUCT(lsCodeLensUserData); struct lsCodeLensCommandArguments { lsDocumentUri uri; lsPosition position; @@ -1184,85 +921,41 @@ struct Ipc_TextDocumentCodeLens : public IpcMessage { lsRequestId id; lsDocumentCodeLensParams params; }; -template -void Reflect(TVisitor& visitor, Ipc_TextDocumentCodeLens& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(id); - REFLECT_MEMBER(params); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(Ipc_TextDocumentCodeLens, id, params); struct Out_TextDocumentCodeLens : public lsOutMessage { lsRequestId id; std::vector> result; }; -template -void Reflect(TVisitor& visitor, Out_TextDocumentCodeLens& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(jsonrpc); - REFLECT_MEMBER(id); - REFLECT_MEMBER(result); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(Out_TextDocumentCodeLens, jsonrpc, id, result); struct Ipc_CodeLensResolve : public IpcMessage { const static IpcId kIpcId = IpcId::CodeLensResolve; lsRequestId id; TCodeLens params; }; -template -void Reflect(TVisitor& visitor, Ipc_CodeLensResolve& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(id); - REFLECT_MEMBER(params); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(Ipc_CodeLensResolve, id, params); struct Out_CodeLensResolve : public lsOutMessage { lsRequestId id; TCodeLens result; }; -template -void Reflect(TVisitor& visitor, Out_CodeLensResolve& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(jsonrpc); - REFLECT_MEMBER(id); - REFLECT_MEMBER(result); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(Out_CodeLensResolve, jsonrpc, id, result); // Search for symbols in the workspace. struct lsWorkspaceSymbolParams { std::string query; }; -template -void Reflect(TVisitor& visitor, lsWorkspaceSymbolParams& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(query); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(lsWorkspaceSymbolParams, query); struct Ipc_WorkspaceSymbol : public IpcMessage { const static IpcId kIpcId = IpcId::WorkspaceSymbol; lsRequestId id; lsWorkspaceSymbolParams params; }; -template -void Reflect(TVisitor& visitor, Ipc_WorkspaceSymbol& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(id); - REFLECT_MEMBER(params); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(Ipc_WorkspaceSymbol, id, params); struct Out_WorkspaceSymbol : public lsOutMessage { lsRequestId id; std::vector result; }; -template -void Reflect(TVisitor& visitor, Out_WorkspaceSymbol& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(jsonrpc); - REFLECT_MEMBER(id); - REFLECT_MEMBER(result); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(Out_WorkspaceSymbol, jsonrpc, id, result); // Show a message to the user. enum class lsMessageType : int { @@ -1276,19 +969,13 @@ struct Out_ShowLogMessageParams { lsMessageType type = lsMessageType::Error; std::string message; }; -template -void Reflect(TVisitor& visitor, Out_ShowLogMessageParams& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(type); - REFLECT_MEMBER(message); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(Out_ShowLogMessageParams, type, message); struct Out_ShowLogMessage : public lsOutMessage { enum class DisplayType { Show, Log }; DisplayType display_type = DisplayType::Show; - + std::string method(); Out_ShowLogMessageParams params; }; diff --git a/src/query.h b/src/query.h index 3e985b24..d3c5c898 100644 --- a/src/query.h +++ b/src/query.h @@ -58,16 +58,7 @@ struct QueryableLocation { interesting < o.interesting; } }; - -template -void Reflect(TVisitor& visitor, QueryableLocation& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(path); - REFLECT_MEMBER(line); - REFLECT_MEMBER(column); - REFLECT_MEMBER(interesting); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(QueryableLocation, path, line, column, interesting); struct UsrRef { Usr usr; @@ -84,14 +75,7 @@ struct UsrRef { return usr < other.usr && loc < other.loc; } }; - -template -void Reflect(TVisitor& visitor, UsrRef& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(usr); - REFLECT_MEMBER(loc); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(UsrRef, usr, loc); // There are two sources of reindex updates: the (single) definition of a // symbol has changed, or one of many users of the symbol has changed. @@ -135,14 +119,7 @@ struct QueryableFile { QueryableFile() {} // For serialization. QueryableFile(const IndexedFile& indexed); }; - -template -void Reflect(TVisitor& visitor, QueryableFile& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(file_id); - REFLECT_MEMBER(outline); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(QueryableFile, file_id, outline); struct QueryableTypeDef { using DefUpdate = TypeDefDefinitionData; @@ -156,15 +133,7 @@ struct QueryableTypeDef { QueryableTypeDef() : def("") {} // For serialization. QueryableTypeDef(IdCache& id_cache, const IndexedTypeDef& indexed); }; - -template -void Reflect(TVisitor& visitor, QueryableTypeDef& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(def); - REFLECT_MEMBER(derived); - REFLECT_MEMBER(uses); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(QueryableTypeDef, def, derived, uses); struct QueryableFuncDef { using DefUpdate = FuncDefDefinitionData; @@ -182,17 +151,7 @@ struct QueryableFuncDef { QueryableFuncDef() : def("") {} // For serialization. QueryableFuncDef(IdCache& id_cache, const IndexedFuncDef& indexed); }; - -template -void Reflect(TVisitor& visitor, QueryableFuncDef& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(def); - REFLECT_MEMBER(declarations); - REFLECT_MEMBER(derived); - REFLECT_MEMBER(callers); - REFLECT_MEMBER(uses); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(QueryableFuncDef, def, declarations, derived, callers, uses); struct QueryableVarDef { using DefUpdate = VarDefDefinitionData; @@ -204,14 +163,7 @@ struct QueryableVarDef { QueryableVarDef() : def("") {} // For serialization. QueryableVarDef(IdCache& id_cache, const IndexedVarDef& indexed); }; - -template -void Reflect(TVisitor& visitor, QueryableVarDef& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(def); - REFLECT_MEMBER(uses); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(QueryableVarDef, def, uses); enum class SymbolKind { Invalid, File, Type, Func, Var }; struct SymbolIdx { @@ -284,31 +236,26 @@ struct IndexUpdate { // Merges the contents of |update| into this IndexUpdate instance. void Merge(const IndexUpdate& update); }; - -template -void Reflect(TVisitor& visitor, IndexUpdate& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(files_removed); - REFLECT_MEMBER(files_added); - REFLECT_MEMBER(files_outline); - REFLECT_MEMBER(types_removed); - REFLECT_MEMBER(types_added); - REFLECT_MEMBER(types_def_changed); - REFLECT_MEMBER(types_derived); - REFLECT_MEMBER(types_uses); - REFLECT_MEMBER(funcs_removed); - REFLECT_MEMBER(funcs_added); - REFLECT_MEMBER(funcs_def_changed); - REFLECT_MEMBER(funcs_declarations); - REFLECT_MEMBER(funcs_derived); - REFLECT_MEMBER(funcs_callers); - REFLECT_MEMBER(funcs_uses); - REFLECT_MEMBER(vars_removed); - REFLECT_MEMBER(vars_added); - REFLECT_MEMBER(vars_def_changed); - REFLECT_MEMBER(vars_uses); - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT(IndexUpdate, + files_removed, + files_added, + files_outline, + types_removed, + types_added, + types_def_changed, + types_derived, + types_uses, + funcs_removed, + funcs_added, + funcs_def_changed, + funcs_declarations, + funcs_derived, + funcs_callers, + funcs_uses, + vars_removed, + vars_added, + vars_def_changed, + vars_uses); // The query database is heavily optimized for fast queries. It is stored diff --git a/src/serializer.h b/src/serializer.h index 3abcb3ea..d1e51b1b 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -38,6 +39,40 @@ struct IndexedFile; value = static_cast(value0); \ } +#define _MAPPABLE_REFLECT_MEMBER(name) \ + REFLECT_MEMBER(name); + +#define MAKE_REFLECT_EMPTY_STRUCT(type, ...) \ + template \ + void Reflect(TVisitor& visitor, type& value) { \ + REFLECT_MEMBER_START(); \ + REFLECT_MEMBER_END(); \ + } + +#define MAKE_REFLECT_STRUCT(type, ...) \ + template \ + void Reflect(TVisitor& visitor, type& value) { \ + REFLECT_MEMBER_START(); \ + MACRO_MAP(_MAPPABLE_REFLECT_MEMBER, __VA_ARGS__) \ + REFLECT_MEMBER_END(); \ + } + + + + + + + + + + + + + + + + + // API: /* @@ -158,156 +193,5 @@ void ReflectMember(Reader& visitor, const char* name, T& value) { } } - - - - - - - - - - - - - -#if false - -void Serialize(Writer& writer, int value); -void Serialize(Writer& writer, const std::string& value); -void Serialize(Writer& writer, Location location); -void Serialize(Writer& writer, uint64_t value); -void Serialize(Writer& writer, IndexedFile& file); - -template -void Serialize(Writer& writer, Id id) { - writer.Uint64(id.id); -} - -template -void Serialize(Writer& writer, optional value) { - if (value) - Serialize(writer, value.value()); - else - writer.Null(); -} - -template -void Serialize(Writer& writer, const std::vector& values) { - writer.StartArray(); - for (const T& value : values) - Serialize(writer, value); - writer.EndArray(); -} - -template -void Serialize(Writer& writer, Ref ref) { - std::string s = std::to_string(ref.id.id) + "@" + ref.loc.ToString(); - writer.String(s.c_str()); -} - -template -void Serialize(Writer& writer, const char* key, const std::vector>& refs) { - if (refs.size() == 0) - return; - - if (key) writer.Key(key); - writer.StartArray(); - for (Ref ref : refs) - Serialize(writer, nullptr, ref); - writer.EndArray(); -} - - - - - -#define SERIALIZE_MEMBER(name) \ - SerializeMember(writer, #name, value.name) -#define SERIALIZE_MEMBER2(name, value) \ - SerializeMember(writer, name, value) -#define DESERIALIZE_MEMBER(name) \ - DeserializeMember(reader, #name, value.name) -#define DESERIALIZE_MEMBER2(name, value) \ - DeserializeMember(reader, name, value) - -// Special templates used by (DE)SERIALIZE_MEMBER macros. -template -void SerializeMember(Writer& writer, const char* name, const T& value) { - writer.Key(name); - Serialize(writer, value); -} -template -void SerializeMember(Writer& writer, const char* name, const std::vector& value) { - if (value.empty()) - return; - writer.Key(name); - Serialize(writer, value); -} -template -void SerializeMember(Writer& writer, const char* name, const optional& value) { - if (!value) - return; - writer.Key(name); - Serialize(writer, value.value()); -} - -void SerializeMember(Writer& writer, const char* name, const std::string& value); - -template -void DeserializeMember(const Reader& reader, const char* name, T& value) { - auto it = reader.FindMember(name); - if (it != reader.MemberEnd()) - Deserialize(it->value, value); -} - - - - - - - -template -void Deserialize(const Reader& reader, Id& output) { - output = Id(reader.GetUint64()); -} - -template -void Deserialize(const Reader& reader, Ref& output) { - const char* str_value = reader.GetString(); - uint64_t id = atoi(str_value); - const char* loc_string = strchr(str_value, '@') + 1; - - output.id = Id(id); - output.loc = Location(loc_string); -} - -template -void Deserialize(const Reader& reader, std::vector& value) { - for (const auto& entry : reader.GetArray()) { - T entry_value; - Deserialize(entry, entry_value); - value.push_back(entry_value); - } -} - -template -void Deserialize(const Reader& reader, optional& value) { - T real_value; - Deserialize(reader, real_value); - value = real_value; -} - -void Deserialize(const Reader& reader, int& value); -void Deserialize(const Reader& reader, bool& value); -void Deserialize(const Reader& reader, std::string& value); -void Deserialize(const Reader& reader, Location& output); -void Deserialize(const Reader& reader, IndexedTypeDef& value); -void Deserialize(const Reader& reader, IndexedFuncDef& value); -void Deserialize(const Reader& reader, IndexedVarDef& value); -void Deserialize(const Reader& reader, IndexedFile& file); - -#endif - std::string Serialize(IndexedFile& file); IndexedFile Deserialize(std::string path, std::string serialized); diff --git a/src/test.cc b/src/test.cc index 1d811ff8..63c66d5d 100644 --- a/src/test.cc +++ b/src/test.cc @@ -99,7 +99,7 @@ void RunTests() { for (std::string path : GetFilesInFolder("tests", true /*recursive*/, true /*add_folder_to_path*/)) { //if (path != "tests/templates/specialized_func_definition.cc") continue; //if (path != "tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc") continue; - if (path != "tests/foo2.cc") continue; + //if (path != "tests/foo2.cc") continue; //if (path != "tests/namespaces/namespace_reference.cc") continue; //if (path != "tests/templates/implicit_variable_instantiation.cc") continue; diff --git a/src/utils.h b/src/utils.h index 60f79fa7..ce07bd70 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include diff --git a/third_party/macro_map.h b/third_party/macro_map.h new file mode 100644 index 00000000..f09ba5b1 --- /dev/null +++ b/third_party/macro_map.h @@ -0,0 +1,134 @@ +/* +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + +// Taken from https://github.com/cbeck88/visit_struct. +// +// Usage +// +// #define PRINT_DOUBLE(x) printf(#x " = %d\n", x); +// +// MACRO_MAP(PRINT_DOUBLE, 1, 2, 3) +// #define PRINT_DOUBLES(...) MACRO_MAP(PRINT_DOUBLE, __VA_ARGS__) + +#pragma once + +static constexpr const int max_visitable_members = 69; + +#define VISIT_STRUCT_EXPAND(x) x +#define VISIT_STRUCT_PP_ARG_N( \ + _1, _2, _3, _4, _5, _6, _7, _8, _9, _10,\ + _11, _12, _13, _14, _15, _16, _17, _18, _19, _20,\ + _21, _22, _23, _24, _25, _26, _27, _28, _29, _30,\ + _31, _32, _33, _34, _35, _36, _37, _38, _39, _40,\ + _41, _42, _43, _44, _45, _46, _47, _48, _49, _50,\ + _51, _52, _53, _54, _55, _56, _57, _58, _59, _60,\ + _61, _62, _63, _64, _65, _66, _67, _68, _69, N, ...) N +#define VISIT_STRUCT_PP_NARG(...) VISIT_STRUCT_EXPAND(VISIT_STRUCT_PP_ARG_N(__VA_ARGS__, \ + 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, \ + 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, \ + 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, \ + 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, \ + 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \ + 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \ + 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) + +/* need extra level to force extra eval */ +#define VISIT_STRUCT_CONCAT_(a,b) a ## b +#define VISIT_STRUCT_CONCAT(a,b) VISIT_STRUCT_CONCAT_(a,b) + +#define VISIT_STRUCT_APPLYF0(f) +#define VISIT_STRUCT_APPLYF1(f,_1) f(_1) +#define VISIT_STRUCT_APPLYF2(f,_1,_2) f(_1) f(_2) +#define VISIT_STRUCT_APPLYF3(f,_1,_2,_3) f(_1) f(_2) f(_3) +#define VISIT_STRUCT_APPLYF4(f,_1,_2,_3,_4) f(_1) f(_2) f(_3) f(_4) +#define VISIT_STRUCT_APPLYF5(f,_1,_2,_3,_4,_5) f(_1) f(_2) f(_3) f(_4) f(_5) +#define VISIT_STRUCT_APPLYF6(f,_1,_2,_3,_4,_5,_6) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) +#define VISIT_STRUCT_APPLYF7(f,_1,_2,_3,_4,_5,_6,_7) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) +#define VISIT_STRUCT_APPLYF8(f,_1,_2,_3,_4,_5,_6,_7,_8) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) +#define VISIT_STRUCT_APPLYF9(f,_1,_2,_3,_4,_5,_6,_7,_8,_9) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) +#define VISIT_STRUCT_APPLYF10(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) +#define VISIT_STRUCT_APPLYF11(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) +#define VISIT_STRUCT_APPLYF12(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) +#define VISIT_STRUCT_APPLYF13(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) +#define VISIT_STRUCT_APPLYF14(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) +#define VISIT_STRUCT_APPLYF15(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) +#define VISIT_STRUCT_APPLYF16(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) +#define VISIT_STRUCT_APPLYF17(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) +#define VISIT_STRUCT_APPLYF18(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) +#define VISIT_STRUCT_APPLYF19(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) +#define VISIT_STRUCT_APPLYF20(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) +#define VISIT_STRUCT_APPLYF21(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) +#define VISIT_STRUCT_APPLYF22(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) +#define VISIT_STRUCT_APPLYF23(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) +#define VISIT_STRUCT_APPLYF24(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) +#define VISIT_STRUCT_APPLYF25(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) +#define VISIT_STRUCT_APPLYF26(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) +#define VISIT_STRUCT_APPLYF27(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) +#define VISIT_STRUCT_APPLYF28(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) +#define VISIT_STRUCT_APPLYF29(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) +#define VISIT_STRUCT_APPLYF30(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) +#define VISIT_STRUCT_APPLYF31(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) +#define VISIT_STRUCT_APPLYF32(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) +#define VISIT_STRUCT_APPLYF33(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) +#define VISIT_STRUCT_APPLYF34(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) +#define VISIT_STRUCT_APPLYF35(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) +#define VISIT_STRUCT_APPLYF36(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) +#define VISIT_STRUCT_APPLYF37(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) +#define VISIT_STRUCT_APPLYF38(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) +#define VISIT_STRUCT_APPLYF39(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) +#define VISIT_STRUCT_APPLYF40(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) +#define VISIT_STRUCT_APPLYF41(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) +#define VISIT_STRUCT_APPLYF42(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) +#define VISIT_STRUCT_APPLYF43(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) +#define VISIT_STRUCT_APPLYF44(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) +#define VISIT_STRUCT_APPLYF45(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) +#define VISIT_STRUCT_APPLYF46(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) +#define VISIT_STRUCT_APPLYF47(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) +#define VISIT_STRUCT_APPLYF48(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) +#define VISIT_STRUCT_APPLYF49(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) +#define VISIT_STRUCT_APPLYF50(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) +#define VISIT_STRUCT_APPLYF51(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) +#define VISIT_STRUCT_APPLYF52(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) +#define VISIT_STRUCT_APPLYF53(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) +#define VISIT_STRUCT_APPLYF54(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) +#define VISIT_STRUCT_APPLYF55(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) +#define VISIT_STRUCT_APPLYF56(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) +#define VISIT_STRUCT_APPLYF57(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) +#define VISIT_STRUCT_APPLYF58(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58) +#define VISIT_STRUCT_APPLYF59(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58) f(_59) +#define VISIT_STRUCT_APPLYF60(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58) f(_59) f(_60) +#define VISIT_STRUCT_APPLYF61(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58) f(_59) f(_60) f(_61) +#define VISIT_STRUCT_APPLYF62(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61,_62) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58) f(_59) f(_60) f(_61) f(_62) +#define VISIT_STRUCT_APPLYF63(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61,_62,_63) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58) f(_59) f(_60) f(_61) f(_62) f(_63) +#define VISIT_STRUCT_APPLYF64(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61,_62,_63,_64) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58) f(_59) f(_60) f(_61) f(_62) f(_63) f(_64) +#define VISIT_STRUCT_APPLYF65(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61,_62,_63,_64,_65) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58) f(_59) f(_60) f(_61) f(_62) f(_63) f(_64) f(_65) +#define VISIT_STRUCT_APPLYF66(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61,_62,_63,_64,_65,_66) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58) f(_59) f(_60) f(_61) f(_62) f(_63) f(_64) f(_65) f(_66) +#define VISIT_STRUCT_APPLYF67(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61,_62,_63,_64,_65,_66,_67) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58) f(_59) f(_60) f(_61) f(_62) f(_63) f(_64) f(_65) f(_66) f(_67) +#define VISIT_STRUCT_APPLYF68(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61,_62,_63,_64,_65,_66,_67,_68) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58) f(_59) f(_60) f(_61) f(_62) f(_63) f(_64) f(_65) f(_66) f(_67) f(_68) +#define VISIT_STRUCT_APPLYF69(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61,_62,_63,_64,_65,_66,_67,_68,_69) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58) f(_59) f(_60) f(_61) f(_62) f(_63) f(_64) f(_65) f(_66) f(_67) f(_68) f(_69) + +#define VISIT_STRUCT_APPLY_F_(M, ...) VISIT_STRUCT_EXPAND(M(__VA_ARGS__)) +#define MACRO_MAP(f, ...) VISIT_STRUCT_EXPAND(VISIT_STRUCT_APPLY_F_(VISIT_STRUCT_CONCAT(VISIT_STRUCT_APPLYF, VISIT_STRUCT_PP_NARG(__VA_ARGS__)), f, __VA_ARGS__))