Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
9b27c7db88 | ||
|
c2ec0d9ce8 |
93
.clang-format
Normal file
93
.clang-format
Normal file
@ -0,0 +1,93 @@
|
||||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: Google
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: true
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlinesLeft: true
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: InlineOnly
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeTernaryOperators: true
|
||||
#BreakConstructorInitializers: BeforeComma
|
||||
BreakConstructorInitializersBeforeComma: true
|
||||
ColumnLimit: 96
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 8
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
IncludeCategories:
|
||||
- Regex: '^<.*\.h>'
|
||||
Priority: 1
|
||||
- Regex: '^<.*'
|
||||
Priority: 2
|
||||
- Regex: '.*'
|
||||
Priority: 3
|
||||
IndentCaseLabels: false
|
||||
SpaceAfterTemplateKeyword: false
|
||||
FixNamespaceComments: true
|
||||
PointerAlignment: Left
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: false
|
||||
PenaltyBreakBeforeFirstCallParameter: 200
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 5000
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 400
|
||||
BreakBeforeInheritanceComma: true
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 2
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Auto
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
...
|
@ -6,12 +6,12 @@ option(WITH_BENCHMARK "enable building benchmark executable" OFF)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
|
||||
set(mstch_VERSION 1.0.1)
|
||||
|
||||
if(NOT MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra -O3")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -Wextra -O3")
|
||||
endif()
|
||||
|
||||
add_subdirectory(src)
|
||||
|
437
CMakeLists.txt.user
Normal file
437
CMakeLists.txt.user
Normal file
@ -0,0 +1,437 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 4.6.0, 2020-02-12T19:36:25. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
<value type="QByteArray">{6c3a783b-4a95-47a1-a553-14efac437a7d}</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
||||
<value type="int">0</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
||||
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
|
||||
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
||||
<value type="QString" key="language">Cpp</value>
|
||||
<valuemap type="QVariantMap" key="value">
|
||||
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
|
||||
</valuemap>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
|
||||
<value type="QString" key="language">QmlJS</value>
|
||||
<valuemap type="QVariantMap" key="value">
|
||||
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
|
||||
</valuemap>
|
||||
</valuemap>
|
||||
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
|
||||
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
|
||||
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
||||
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
||||
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
||||
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
||||
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
||||
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
||||
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
||||
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
|
||||
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
||||
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
|
||||
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
|
||||
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
||||
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
||||
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
||||
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
||||
<value type="int" key="EditorConfiguration.Utf8BomBehavior">2</value>
|
||||
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
||||
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
|
||||
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
||||
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.PluginSettings</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/>
|
||||
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Target.0</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Unnamed</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Unnamed</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{85ec3516-307e-4a38-9ec9-10c74ad47576}</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||
<valuelist type="QVariantList" key="CMake.Configuration">
|
||||
<value type="QString">CMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx}</value>
|
||||
<value type="QString">CMAKE_C_COMPILER:STRING=%{Compiler:Executable:C}</value>
|
||||
<value type="QString">CMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX}</value>
|
||||
<value type="QString">QT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable}</value>
|
||||
<value type="QString">WITH_UNIT_TESTS:BOOL=ON</value>
|
||||
</valuelist>
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/msd/work/build-mstch-Unnamed-Default</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString">all</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">CMake Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString">clean</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">CMake Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Default</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Default</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
|
||||
<valuelist type="QVariantList" key="CMake.Configuration">
|
||||
<value type="QString">CMAKE_BUILD_TYPE:STRING=Debug</value>
|
||||
</valuelist>
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/msd/work/build-mstch-Unnamed-Debug</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString">all</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">CMake Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString">clean</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">CMake Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
|
||||
<valuelist type="QVariantList" key="CMake.Configuration">
|
||||
<value type="QString">CMAKE_BUILD_TYPE:STRING=Release</value>
|
||||
</valuelist>
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/msd/work/build-mstch-Unnamed-Release</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString">all</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">CMake Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString">clean</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">CMake Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.3">
|
||||
<valuelist type="QVariantList" key="CMake.Configuration">
|
||||
<value type="QString">CMAKE_BUILD_TYPE:STRING=RelWithDebInfo</value>
|
||||
</valuelist>
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/msd/work/build-mstch-Unnamed-Release with Debug Information</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString">all</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">CMake Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString">clean</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">CMake Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release with Debug Information</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release with Debug Information</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.4">
|
||||
<valuelist type="QVariantList" key="CMake.Configuration">
|
||||
<value type="QString">CMAKE_BUILD_TYPE:STRING=MinSizeRel</value>
|
||||
</valuelist>
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/msd/work/build-mstch-Unnamed-Minimum Size Release</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString">all</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">CMake Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString">clean</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">CMake Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Minimum Size Release</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Minimum Size Release</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">5</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy Configuration</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
|
||||
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
|
||||
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
|
||||
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
|
||||
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
|
||||
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
|
||||
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
|
||||
<value type="int">0</value>
|
||||
<value type="int">1</value>
|
||||
<value type="int">2</value>
|
||||
<value type="int">3</value>
|
||||
<value type="int">4</value>
|
||||
<value type="int">5</value>
|
||||
<value type="int">6</value>
|
||||
<value type="int">7</value>
|
||||
<value type="int">8</value>
|
||||
<value type="int">9</value>
|
||||
<value type="int">10</value>
|
||||
<value type="int">11</value>
|
||||
<value type="int">12</value>
|
||||
<value type="int">13</value>
|
||||
<value type="int">14</value>
|
||||
</valuelist>
|
||||
<value type="QString" key="CMakeProjectManager.CMakeRunConfiguation.Title">headerize</value>
|
||||
<value type="QString" key="CMakeProjectManager.CMakeRunConfiguration.Arguments"></value>
|
||||
<value type="QString" key="CMakeProjectManager.CMakeRunConfiguration.UserWorkingDirectory"></value>
|
||||
<value type="QString" key="CMakeProjectManager.CMakeRunConfiguration.UserWorkingDirectory.default">/tmp/QtCreator-poSNJS/qtc-cmake-DajvkCJW/vendor/headerize/src</value>
|
||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">headerize</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeRunConfiguration.headerize</value>
|
||||
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.1">
|
||||
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
|
||||
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
|
||||
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
|
||||
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
|
||||
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
|
||||
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
|
||||
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
|
||||
<value type="int">0</value>
|
||||
<value type="int">1</value>
|
||||
<value type="int">2</value>
|
||||
<value type="int">3</value>
|
||||
<value type="int">4</value>
|
||||
<value type="int">5</value>
|
||||
<value type="int">6</value>
|
||||
<value type="int">7</value>
|
||||
<value type="int">8</value>
|
||||
<value type="int">9</value>
|
||||
<value type="int">10</value>
|
||||
<value type="int">11</value>
|
||||
<value type="int">12</value>
|
||||
<value type="int">13</value>
|
||||
<value type="int">14</value>
|
||||
</valuelist>
|
||||
<value type="QString" key="CMakeProjectManager.CMakeRunConfiguation.Title">mstch_test</value>
|
||||
<value type="QString" key="CMakeProjectManager.CMakeRunConfiguration.Arguments"></value>
|
||||
<value type="QString" key="CMakeProjectManager.CMakeRunConfiguration.UserWorkingDirectory"></value>
|
||||
<value type="QString" key="CMakeProjectManager.CMakeRunConfiguration.UserWorkingDirectory.default">/tmp/QtCreator-poSNJS/qtc-cmake-DajvkCJW/test</value>
|
||||
<value type="int" key="PE.EnvironmentAspect.Base">-1</value>
|
||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">mstch_test</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeRunConfiguration.mstch_test</value>
|
||||
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">2</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.TargetCount</variable>
|
||||
<value type="int">1</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
||||
<value type="int">18</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>Version</variable>
|
||||
<value type="int">18</value>
|
||||
</data>
|
||||
</qtcreator>
|
@ -1,62 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
namespace mstch {
|
||||
|
||||
struct config {
|
||||
static std::function<std::string(const std::string&)> escape;
|
||||
static std::function<std::string(const std::string&)> escape;
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<class N>
|
||||
class object_t {
|
||||
public:
|
||||
const N& at(const std::string& name) const {
|
||||
cache[name] = (methods.at(name))();
|
||||
return cache[name];
|
||||
}
|
||||
public:
|
||||
const N& at(const std::string& name) const {
|
||||
cache[name] = (methods.at(name))();
|
||||
return cache[name];
|
||||
}
|
||||
|
||||
bool has(const std::string name) const {
|
||||
return methods.count(name) != 0;
|
||||
}
|
||||
bool has(const std::string name) const { return methods.count(name) != 0; }
|
||||
|
||||
protected:
|
||||
template<class S>
|
||||
void register_methods(S* s, std::map<std::string,N(S::*)()> methods) {
|
||||
for(auto& item: methods)
|
||||
this->methods.insert({item.first, std::bind(item.second, s)});
|
||||
}
|
||||
protected:
|
||||
template<class S>
|
||||
void register_methods(S* s, std::map<std::string, N (S::*)()> methods) {
|
||||
for (auto& item : methods)
|
||||
this->methods.insert({item.first, std::bind(item.second, s)});
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<std::string, std::function<N()>> methods;
|
||||
mutable std::map<std::string, N> cache;
|
||||
private:
|
||||
std::map<std::string, std::function<N()>> methods;
|
||||
mutable std::map<std::string, N> cache;
|
||||
};
|
||||
|
||||
template<class T, class N>
|
||||
class is_fun {
|
||||
private:
|
||||
using not_fun = char;
|
||||
using fun_without_args = char[2];
|
||||
using fun_with_args = char[3];
|
||||
template <typename U, U> struct really_has;
|
||||
template <typename C> static fun_without_args& test(
|
||||
really_has<N(C::*)() const, &C::operator()>*);
|
||||
template <typename C> static fun_with_args& test(
|
||||
really_has<N(C::*)(const std::string&) const,
|
||||
&C::operator()>*);
|
||||
template <typename> static not_fun& test(...);
|
||||
private:
|
||||
using not_fun = char;
|
||||
using fun_without_args = char[2];
|
||||
using fun_with_args = char[3];
|
||||
template<typename U, U>
|
||||
struct really_has;
|
||||
template<typename C>
|
||||
static fun_without_args& test(really_has<N (C::*)() const, &C::operator()>*);
|
||||
template<typename C>
|
||||
static fun_with_args& test(really_has<N (C::*)(const std::string&) const, &C::operator()>*);
|
||||
template<typename>
|
||||
static not_fun& test(...);
|
||||
|
||||
public:
|
||||
static bool const no_args = sizeof(test<T>(0)) == sizeof(fun_without_args);
|
||||
static bool const has_args = sizeof(test<T>(0)) == sizeof(fun_with_args);
|
||||
public:
|
||||
static bool const no_args = sizeof(test<T>(0)) == sizeof(fun_without_args);
|
||||
static bool const has_args = sizeof(test<T>(0)) == sizeof(fun_with_args);
|
||||
};
|
||||
|
||||
template<class N>
|
||||
@ -64,50 +62,68 @@ using node_renderer = std::function<std::string(const N& n)>;
|
||||
|
||||
template<class N>
|
||||
class lambda_t {
|
||||
public:
|
||||
template<class F>
|
||||
lambda_t(F f, typename std::enable_if<is_fun<F, N>::no_args>::type* = 0):
|
||||
fun([f](node_renderer<N> renderer, const std::string&) {
|
||||
return renderer(f());
|
||||
})
|
||||
{
|
||||
}
|
||||
public:
|
||||
template<class F>
|
||||
lambda_t(F f, typename std::enable_if<is_fun<F, N>::no_args>::type* = 0)
|
||||
: fun([f](node_renderer<N> renderer, const std::string&) { return renderer(f()); })
|
||||
{}
|
||||
|
||||
template<class F>
|
||||
lambda_t(F f, typename std::enable_if<is_fun<F, N>::has_args>::type* = 0):
|
||||
fun([f](node_renderer<N> renderer, const std::string& text) {
|
||||
return renderer(f(text));
|
||||
})
|
||||
{
|
||||
}
|
||||
template<class F>
|
||||
lambda_t(F f, typename std::enable_if<is_fun<F, N>::has_args>::type* = 0)
|
||||
: fun([f](node_renderer<N> renderer, const std::string& text) {
|
||||
return renderer(f(text));
|
||||
})
|
||||
{}
|
||||
|
||||
std::string operator()(node_renderer<N> renderer,
|
||||
const std::string& text = "") const
|
||||
{
|
||||
return fun(renderer, text);
|
||||
}
|
||||
std::string operator()(node_renderer<N> renderer, const std::string& text = "") const {
|
||||
return fun(renderer, text);
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<std::string(node_renderer<N> renderer, const std::string&)> fun;
|
||||
private:
|
||||
std::function<std::string(node_renderer<N> renderer, const std::string&)> fun;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace internal
|
||||
|
||||
struct object_wrapper;
|
||||
struct map_wrapper;
|
||||
struct array_wrapper;
|
||||
struct lambda_wrapper;
|
||||
|
||||
using node = std::variant<std::nullptr_t,
|
||||
std::string,
|
||||
int,
|
||||
double,
|
||||
bool,
|
||||
lambda_wrapper,
|
||||
object_wrapper,
|
||||
map_wrapper,
|
||||
array_wrapper>;
|
||||
|
||||
using node = boost::make_recursive_variant<
|
||||
std::nullptr_t, std::string, int, double, bool,
|
||||
internal::lambda_t<boost::recursive_variant_>,
|
||||
std::shared_ptr<internal::object_t<boost::recursive_variant_>>,
|
||||
std::map<const std::string, boost::recursive_variant_>,
|
||||
std::vector<boost::recursive_variant_>>::type;
|
||||
using object = internal::object_t<node>;
|
||||
using lambda = internal::lambda_t<node>;
|
||||
using map = std::map<const std::string, node>;
|
||||
using array = std::vector<node>;
|
||||
using map = std::map<const std::string, node>;
|
||||
using array = std::vector<node>;
|
||||
|
||||
std::string render(
|
||||
const std::string& tmplt,
|
||||
const node& root,
|
||||
const std::map<std::string,std::string>& partials =
|
||||
std::map<std::string,std::string>());
|
||||
struct array_wrapper {
|
||||
array values;
|
||||
};
|
||||
|
||||
}
|
||||
struct map_wrapper {
|
||||
map values;
|
||||
};
|
||||
|
||||
struct object_wrapper {
|
||||
std::shared_ptr<object> values;
|
||||
};
|
||||
|
||||
struct lambda_wrapper {
|
||||
lambda values;
|
||||
};
|
||||
|
||||
std::string render(const std::string& tmplt,
|
||||
const node& root,
|
||||
const std::map<std::string, std::string>& partials =
|
||||
std::map<std::string, std::string>());
|
||||
|
||||
} // namespace mstch
|
||||
|
@ -1,11 +1,8 @@
|
||||
find_package(Boost 1.54 REQUIRED)
|
||||
|
||||
set(mstch_INCLUDE_DIR
|
||||
${PROJECT_SOURCE_DIR}/include CACHE STRING "mstch include directory")
|
||||
|
||||
include_directories(
|
||||
${mstch_INCLUDE_DIR}
|
||||
${Boost_INCLUDE_DIR})
|
||||
${mstch_INCLUDE_DIR})
|
||||
|
||||
set(SRC
|
||||
state/in_section.cpp
|
||||
|
@ -7,14 +7,13 @@ using namespace mstch;
|
||||
|
||||
std::function<std::string(const std::string&)> mstch::config::escape;
|
||||
|
||||
std::string mstch::render(
|
||||
const std::string& tmplt,
|
||||
const node& root,
|
||||
const std::map<std::string,std::string>& partials)
|
||||
std::string mstch::render(const std::string& tmplt,
|
||||
const node& root,
|
||||
const std::map<std::string, std::string>& partials)
|
||||
{
|
||||
std::map<std::string, template_type> partial_templates;
|
||||
for (auto& partial: partials)
|
||||
partial_templates.insert({partial.first, {partial.second}});
|
||||
std::map<std::string, template_type> partial_templates;
|
||||
for (auto& partial : partials)
|
||||
partial_templates.insert({partial.first, {partial.second}});
|
||||
|
||||
return render_context(root, partial_templates).render(tmplt);
|
||||
return render_context(root, partial_templates).render(tmplt);
|
||||
}
|
||||
|
@ -6,67 +6,62 @@ using namespace mstch;
|
||||
|
||||
const mstch::node render_context::null_node;
|
||||
|
||||
render_context::push::push(render_context& context, const mstch::node& node):
|
||||
m_context(context)
|
||||
render_context::push::push(render_context& context, const mstch::node& node)
|
||||
: m_context(context)
|
||||
{
|
||||
context.m_nodes.emplace_front(node);
|
||||
context.m_node_ptrs.emplace_front(&node);
|
||||
context.m_state.push(std::unique_ptr<render_state>(new outside_section));
|
||||
context.m_nodes.emplace_front(node);
|
||||
context.m_node_ptrs.emplace_front(&node);
|
||||
context.m_state.push(std::unique_ptr<render_state>(new outside_section));
|
||||
}
|
||||
|
||||
render_context::push::~push() {
|
||||
m_context.m_nodes.pop_front();
|
||||
m_context.m_node_ptrs.pop_front();
|
||||
m_context.m_state.pop();
|
||||
m_context.m_nodes.pop_front();
|
||||
m_context.m_node_ptrs.pop_front();
|
||||
m_context.m_state.pop();
|
||||
}
|
||||
|
||||
std::string render_context::push::render(const template_type& templt) {
|
||||
return m_context.render(templt);
|
||||
return m_context.render(templt);
|
||||
}
|
||||
|
||||
render_context::render_context(
|
||||
const mstch::node& node,
|
||||
const std::map<std::string, template_type>& partials):
|
||||
m_partials(partials), m_nodes(1, node), m_node_ptrs(1, &node)
|
||||
render_context::render_context(const mstch::node& node,
|
||||
const std::map<std::string, template_type>& partials)
|
||||
: m_partials(partials), m_nodes(1, node), m_node_ptrs(1, &node)
|
||||
{
|
||||
m_state.push(std::unique_ptr<render_state>(new outside_section));
|
||||
m_state.push(std::unique_ptr<render_state>(new outside_section));
|
||||
}
|
||||
|
||||
const mstch::node& render_context::find_node(
|
||||
const std::string& token,
|
||||
std::list<node const*> current_nodes)
|
||||
const mstch::node& render_context::find_node(const std::string& token,
|
||||
std::list<node const*> current_nodes)
|
||||
{
|
||||
if (token != "." && token.find('.') != std::string::npos)
|
||||
return find_node(token.substr(token.rfind('.') + 1),
|
||||
{&find_node(token.substr(0, token.rfind('.')), current_nodes)});
|
||||
else
|
||||
for (auto& node: current_nodes)
|
||||
if (visit(has_token(token), *node))
|
||||
return visit(get_token(token, *node), *node);
|
||||
return null_node;
|
||||
if (token != "." && token.find('.') != std::string::npos)
|
||||
return find_node(token.substr(token.rfind('.') + 1),
|
||||
{&find_node(token.substr(0, token.rfind('.')), current_nodes)});
|
||||
else
|
||||
for (auto& node : current_nodes)
|
||||
if (visit(has_token(token), *node))
|
||||
return visit(get_token(token, *node), *node);
|
||||
return null_node;
|
||||
}
|
||||
|
||||
const mstch::node& render_context::get_node(const std::string& token) {
|
||||
return find_node(token, m_node_ptrs);
|
||||
}
|
||||
|
||||
std::string render_context::render(
|
||||
const template_type& templt, const std::string& prefix)
|
||||
{
|
||||
std::string output;
|
||||
bool prev_eol = true;
|
||||
for (auto& token: templt) {
|
||||
if (prev_eol && prefix.length() != 0)
|
||||
output += m_state.top()->render(*this, {prefix});
|
||||
output += m_state.top()->render(*this, token);
|
||||
prev_eol = token.eol();
|
||||
}
|
||||
return output;
|
||||
std::string render_context::render(const template_type& templt, const std::string& prefix) {
|
||||
std::string output;
|
||||
bool prev_eol = true;
|
||||
for (auto& token : templt) {
|
||||
if (prev_eol && prefix.length() != 0)
|
||||
output += m_state.top()->render(*this, {prefix});
|
||||
output += m_state.top()->render(*this, token);
|
||||
prev_eol = token.eol();
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
std::string render_context::render_partial(
|
||||
const std::string& partial_name, const std::string& prefix)
|
||||
std::string render_context::render_partial(const std::string& partial_name,
|
||||
const std::string& prefix)
|
||||
{
|
||||
return m_partials.count(partial_name) ?
|
||||
render(m_partials.at(partial_name), prefix) : "";
|
||||
return m_partials.count(partial_name) ? render(m_partials.at(partial_name), prefix) : "";
|
||||
}
|
||||
|
@ -3,8 +3,8 @@
|
||||
#include <deque>
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
|
||||
#include "mstch/mstch.hpp"
|
||||
#include "state/render_state.hpp"
|
||||
@ -13,39 +13,35 @@
|
||||
namespace mstch {
|
||||
|
||||
class render_context {
|
||||
public:
|
||||
class push {
|
||||
public:
|
||||
push(render_context& context, const mstch::node& node = {});
|
||||
~push();
|
||||
std::string render(const template_type& templt);
|
||||
private:
|
||||
render_context& m_context;
|
||||
};
|
||||
public:
|
||||
class push {
|
||||
public:
|
||||
push(render_context& context, const mstch::node& node = {});
|
||||
~push();
|
||||
std::string render(const template_type& templt);
|
||||
|
||||
render_context(
|
||||
const mstch::node& node,
|
||||
const std::map<std::string, template_type>& partials);
|
||||
const mstch::node& get_node(const std::string& token);
|
||||
std::string render(
|
||||
const template_type& templt, const std::string& prefix = "");
|
||||
std::string render_partial(
|
||||
const std::string& partial_name, const std::string& prefix);
|
||||
template<class T, class... Args>
|
||||
void set_state(Args&& ... args) {
|
||||
m_state.top() = std::unique_ptr<render_state>(
|
||||
new T(std::forward<Args>(args)...));
|
||||
}
|
||||
private:
|
||||
render_context& m_context;
|
||||
};
|
||||
|
||||
private:
|
||||
static const mstch::node null_node;
|
||||
const mstch::node& find_node(
|
||||
const std::string& token,
|
||||
std::list<node const*> current_nodes);
|
||||
std::map<std::string, template_type> m_partials;
|
||||
std::deque<mstch::node> m_nodes;
|
||||
std::list<const mstch::node*> m_node_ptrs;
|
||||
std::stack<std::unique_ptr<render_state>> m_state;
|
||||
render_context(const mstch::node& node,
|
||||
const std::map<std::string, template_type>& partials);
|
||||
const mstch::node& get_node(const std::string& token);
|
||||
std::string render(const template_type& templt, const std::string& prefix = "");
|
||||
std::string render_partial(const std::string& partial_name, const std::string& prefix);
|
||||
template<class T, class... Args>
|
||||
void set_state(Args&&... args) {
|
||||
m_state.top() = std::unique_ptr<render_state>(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
private:
|
||||
static const mstch::node null_node;
|
||||
const mstch::node& find_node(const std::string& token,
|
||||
std::list<node const*> current_nodes);
|
||||
std::map<std::string, template_type> m_partials;
|
||||
std::deque<mstch::node> m_nodes;
|
||||
std::list<const mstch::node*> m_node_ptrs;
|
||||
std::stack<std::unique_ptr<render_state>> m_state;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace mstch
|
||||
|
@ -5,30 +5,30 @@
|
||||
|
||||
using namespace mstch;
|
||||
|
||||
in_section::in_section(type type, const token& start_token):
|
||||
m_type(type), m_start_token(start_token), m_skipped_openings(0)
|
||||
in_section::in_section(type type, const token& start_token)
|
||||
: m_type(type), m_start_token(start_token), m_skipped_openings(0)
|
||||
{
|
||||
}
|
||||
|
||||
std::string in_section::render(render_context& ctx, const token& token) {
|
||||
if (token.token_type() == token::type::section_close)
|
||||
if (token.name() == m_start_token.name() && m_skipped_openings == 0) {
|
||||
auto& node = ctx.get_node(m_start_token.name());
|
||||
std::string out;
|
||||
if (token.token_type() == token::type::section_close)
|
||||
if (token.name() == m_start_token.name() && m_skipped_openings == 0) {
|
||||
auto& node = ctx.get_node(m_start_token.name());
|
||||
std::string out;
|
||||
|
||||
if (m_type == type::normal && !visit(is_node_empty(), node))
|
||||
out = visit(render_section(ctx, m_section, m_start_token.delims()), node);
|
||||
else if (m_type == type::inverted && visit(is_node_empty(), node))
|
||||
out = render_context::push(ctx).render(m_section);
|
||||
if (m_type == type::normal && !visit(is_node_empty(), node))
|
||||
out = visit(render_section(ctx, m_section, m_start_token.delims()), node);
|
||||
else if (m_type == type::inverted && visit(is_node_empty(), node))
|
||||
out = render_context::push(ctx).render(m_section);
|
||||
|
||||
ctx.set_state<outside_section>();
|
||||
return out;
|
||||
} else
|
||||
m_skipped_openings--;
|
||||
else if (token.token_type() == token::type::inverted_section_open ||
|
||||
token.token_type() == token::type::section_open)
|
||||
m_skipped_openings++;
|
||||
ctx.set_state<outside_section>();
|
||||
return out;
|
||||
} else
|
||||
m_skipped_openings--;
|
||||
else if (token.token_type() == token::type::inverted_section_open ||
|
||||
token.token_type() == token::type::section_open)
|
||||
m_skipped_openings++;
|
||||
|
||||
m_section << token;
|
||||
return "";
|
||||
m_section << token;
|
||||
return "";
|
||||
}
|
||||
|
@ -8,17 +8,17 @@
|
||||
|
||||
namespace mstch {
|
||||
|
||||
class in_section: public render_state {
|
||||
public:
|
||||
enum class type { inverted, normal };
|
||||
in_section(type type, const token& start_token);
|
||||
std::string render(render_context& context, const token& token) override;
|
||||
class in_section : public render_state {
|
||||
public:
|
||||
enum class type { inverted, normal };
|
||||
in_section(type type, const token& start_token);
|
||||
std::string render(render_context& context, const token& token) override;
|
||||
|
||||
private:
|
||||
const type m_type;
|
||||
const token& m_start_token;
|
||||
template_type m_section;
|
||||
int m_skipped_openings;
|
||||
private:
|
||||
const type m_type;
|
||||
const token& m_start_token;
|
||||
template_type m_section;
|
||||
int m_skipped_openings;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace mstch
|
||||
|
@ -1,32 +1,30 @@
|
||||
#include "outside_section.hpp"
|
||||
|
||||
#include "visitor/render_node.hpp"
|
||||
#include "in_section.hpp"
|
||||
#include "render_context.hpp"
|
||||
#include "visitor/render_node.hpp"
|
||||
|
||||
using namespace mstch;
|
||||
|
||||
std::string outside_section::render(
|
||||
render_context& ctx, const token& token)
|
||||
{
|
||||
using flag = render_node::flag;
|
||||
switch (token.token_type()) {
|
||||
std::string outside_section::render(render_context& ctx, const token& token) {
|
||||
using flag = render_node::flag;
|
||||
switch (token.token_type()) {
|
||||
case token::type::section_open:
|
||||
ctx.set_state<in_section>(in_section::type::normal, token);
|
||||
break;
|
||||
ctx.set_state<in_section>(in_section::type::normal, token);
|
||||
break;
|
||||
case token::type::inverted_section_open:
|
||||
ctx.set_state<in_section>(in_section::type::inverted, token);
|
||||
break;
|
||||
ctx.set_state<in_section>(in_section::type::inverted, token);
|
||||
break;
|
||||
case token::type::variable:
|
||||
return visit(render_node(ctx, flag::escape_html), ctx.get_node(token.name()));
|
||||
return visit(render_node(ctx, flag::escape_html), ctx.get_node(token.name()));
|
||||
case token::type::unescaped_variable:
|
||||
return visit(render_node(ctx, flag::none), ctx.get_node(token.name()));
|
||||
return visit(render_node(ctx, flag::none), ctx.get_node(token.name()));
|
||||
case token::type::text:
|
||||
return token.raw();
|
||||
return token.raw();
|
||||
case token::type::partial:
|
||||
return ctx.render_partial(token.name(), token.partial_prefix());
|
||||
return ctx.render_partial(token.name(), token.partial_prefix());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "";
|
||||
break;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
@ -4,9 +4,9 @@
|
||||
|
||||
namespace mstch {
|
||||
|
||||
class outside_section: public render_state {
|
||||
public:
|
||||
std::string render(render_context& context, const token& token) override;
|
||||
class outside_section : public render_state {
|
||||
public:
|
||||
std::string render(render_context& context, const token& token) override;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace mstch
|
||||
|
@ -9,9 +9,9 @@ namespace mstch {
|
||||
class render_context;
|
||||
|
||||
class render_state {
|
||||
public:
|
||||
virtual ~render_state() {}
|
||||
virtual std::string render(render_context& context, const token& token) = 0;
|
||||
public:
|
||||
virtual ~render_state() {}
|
||||
virtual std::string render(render_context& context, const token& token) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace mstch
|
||||
|
@ -2,103 +2,98 @@
|
||||
|
||||
using namespace mstch;
|
||||
|
||||
template_type::template_type(const std::string& str, const delim_type& delims):
|
||||
m_open(delims.first), m_close(delims.second)
|
||||
template_type::template_type(const std::string& str, const delim_type& delims)
|
||||
: m_open(delims.first), m_close(delims.second)
|
||||
{
|
||||
tokenize(str);
|
||||
strip_whitespace();
|
||||
tokenize(str);
|
||||
strip_whitespace();
|
||||
}
|
||||
|
||||
template_type::template_type(const std::string& str):
|
||||
m_open("{{"), m_close("}}")
|
||||
{
|
||||
tokenize(str);
|
||||
strip_whitespace();
|
||||
template_type::template_type(const std::string& str) : m_open("{{"), m_close("}}") {
|
||||
tokenize(str);
|
||||
strip_whitespace();
|
||||
}
|
||||
|
||||
void template_type::process_text(citer begin, citer end) {
|
||||
if (begin == end)
|
||||
return;
|
||||
auto start = begin;
|
||||
for (auto it = begin; it != end; ++it)
|
||||
if (*it == '\n' || it == end - 1) {
|
||||
m_tokens.push_back({{start, it + 1}});
|
||||
start = it + 1;
|
||||
}
|
||||
if (begin == end)
|
||||
return;
|
||||
auto start = begin;
|
||||
for (auto it = begin; it != end; ++it)
|
||||
if (*it == '\n' || it == end - 1) {
|
||||
m_tokens.push_back({{start, it + 1}});
|
||||
start = it + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void template_type::tokenize(const std::string& tmp) {
|
||||
citer beg = tmp.begin();
|
||||
auto npos = std::string::npos;
|
||||
citer beg = tmp.begin();
|
||||
auto npos = std::string::npos;
|
||||
|
||||
for (std::size_t cur_pos = 0; cur_pos < tmp.size();) {
|
||||
auto open_pos = tmp.find(m_open, cur_pos);
|
||||
auto close_pos = tmp.find(
|
||||
m_close, open_pos == npos ? open_pos : open_pos + 1);
|
||||
for (std::size_t cur_pos = 0; cur_pos < tmp.size();) {
|
||||
auto open_pos = tmp.find(m_open, cur_pos);
|
||||
auto close_pos = tmp.find(m_close, open_pos == npos ? open_pos : open_pos + 1);
|
||||
|
||||
if (close_pos != npos && open_pos != npos) {
|
||||
if (*(beg + open_pos + m_open.size()) == '{' &&
|
||||
*(beg + close_pos + m_close.size()) == '}')
|
||||
++close_pos;
|
||||
if (close_pos != npos && open_pos != npos) {
|
||||
if (*(beg + open_pos + m_open.size()) == '{' &&
|
||||
*(beg + close_pos + m_close.size()) == '}')
|
||||
++close_pos;
|
||||
|
||||
process_text(beg + cur_pos, beg + open_pos);
|
||||
cur_pos = close_pos + m_close.size();
|
||||
m_tokens.push_back({{beg + open_pos, beg + close_pos + m_close.size()},
|
||||
m_open.size(), m_close.size()});
|
||||
process_text(beg + cur_pos, beg + open_pos);
|
||||
cur_pos = close_pos + m_close.size();
|
||||
m_tokens.push_back({{beg + open_pos, beg + close_pos + m_close.size()},
|
||||
m_open.size(),
|
||||
m_close.size()});
|
||||
|
||||
if (cur_pos == tmp.size()) {
|
||||
m_tokens.push_back({{""}});
|
||||
m_tokens.back().eol(true);
|
||||
}
|
||||
if (cur_pos == tmp.size()) {
|
||||
m_tokens.push_back({{""}});
|
||||
m_tokens.back().eol(true);
|
||||
}
|
||||
|
||||
if (*(beg + open_pos + m_open.size()) == '=' &&
|
||||
*(beg + close_pos - 1) == '=')
|
||||
{
|
||||
auto tok_beg = beg + open_pos + m_open.size() + 1;
|
||||
auto tok_end = beg + close_pos - 1;
|
||||
auto front_skip = first_not_ws(tok_beg, tok_end);
|
||||
auto back_skip = first_not_ws(reverse(tok_end), reverse(tok_beg));
|
||||
m_open = {front_skip, beg + tmp.find(' ', front_skip - beg)};
|
||||
m_close = {beg + tmp.rfind(' ', back_skip - beg) + 1, back_skip + 1};
|
||||
}
|
||||
} else {
|
||||
process_text(beg + cur_pos, tmp.end());
|
||||
cur_pos = close_pos;
|
||||
if (*(beg + open_pos + m_open.size()) == '=' && *(beg + close_pos - 1) == '=') {
|
||||
auto tok_beg = beg + open_pos + m_open.size() + 1;
|
||||
auto tok_end = beg + close_pos - 1;
|
||||
auto front_skip = first_not_ws(tok_beg, tok_end);
|
||||
auto back_skip = first_not_ws(reverse(tok_end), reverse(tok_beg));
|
||||
m_open = {front_skip, beg + tmp.find(' ', front_skip - beg)};
|
||||
m_close = {beg + tmp.rfind(' ', back_skip - beg) + 1, back_skip + 1};
|
||||
}
|
||||
} else {
|
||||
process_text(beg + cur_pos, tmp.end());
|
||||
cur_pos = close_pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void template_type::strip_whitespace() {
|
||||
auto line_begin = m_tokens.begin();
|
||||
bool has_tag = false, non_space = false;
|
||||
auto line_begin = m_tokens.begin();
|
||||
bool has_tag = false, non_space = false;
|
||||
|
||||
for (auto it = m_tokens.begin(); it != m_tokens.end(); ++it) {
|
||||
auto type = (*it).token_type();
|
||||
if (type != token::type::text && type != token::type::variable &&
|
||||
type != token::type::unescaped_variable)
|
||||
has_tag = true;
|
||||
else if (!(*it).ws_only())
|
||||
non_space = true;
|
||||
for (auto it = m_tokens.begin(); it != m_tokens.end(); ++it) {
|
||||
auto type = (*it).token_type();
|
||||
if (type != token::type::text && type != token::type::variable &&
|
||||
type != token::type::unescaped_variable)
|
||||
has_tag = true;
|
||||
else if (!(*it).ws_only())
|
||||
non_space = true;
|
||||
|
||||
if ((*it).eol()) {
|
||||
if (has_tag && !non_space) {
|
||||
store_prefixes(line_begin);
|
||||
if ((*it).eol()) {
|
||||
if (has_tag && !non_space) {
|
||||
store_prefixes(line_begin);
|
||||
|
||||
auto c = line_begin;
|
||||
for (bool end = false; !end; (*c).ws_only() ? c = m_tokens.erase(c) : ++c)
|
||||
if ((end = (*c).eol()))
|
||||
it = c - 1;
|
||||
}
|
||||
auto c = line_begin;
|
||||
for (bool end = false; !end; (*c).ws_only() ? c = m_tokens.erase(c) : ++c)
|
||||
if ((end = (*c).eol()))
|
||||
it = c - 1;
|
||||
}
|
||||
|
||||
non_space = has_tag = false;
|
||||
line_begin = it + 1;
|
||||
non_space = has_tag = false;
|
||||
line_begin = it + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void template_type::store_prefixes(std::vector<token>::iterator beg) {
|
||||
for (auto cur = beg; !(*cur).eol(); ++cur)
|
||||
if ((*cur).token_type() == token::type::partial &&
|
||||
cur != beg && (*(cur - 1)).ws_only())
|
||||
(*cur).partial_prefix((*(cur - 1)).raw());
|
||||
for (auto cur = beg; !(*cur).eol(); ++cur)
|
||||
if ((*cur).token_type() == token::type::partial && cur != beg && (*(cur - 1)).ws_only())
|
||||
(*cur).partial_prefix((*(cur - 1)).raw());
|
||||
}
|
||||
|
@ -9,22 +9,22 @@
|
||||
namespace mstch {
|
||||
|
||||
class template_type {
|
||||
public:
|
||||
template_type() = default;
|
||||
template_type(const std::string& str);
|
||||
template_type(const std::string& str, const delim_type& delims);
|
||||
std::vector<token>::const_iterator begin() const { return m_tokens.begin(); }
|
||||
std::vector<token>::const_iterator end() const { return m_tokens.end(); }
|
||||
void operator<<(const token& token) { m_tokens.push_back(token); }
|
||||
public:
|
||||
template_type() = default;
|
||||
template_type(const std::string& str);
|
||||
template_type(const std::string& str, const delim_type& delims);
|
||||
std::vector<token>::const_iterator begin() const { return m_tokens.begin(); }
|
||||
std::vector<token>::const_iterator end() const { return m_tokens.end(); }
|
||||
void operator<<(const token& token) { m_tokens.push_back(token); }
|
||||
|
||||
private:
|
||||
std::vector<token> m_tokens;
|
||||
std::string m_open;
|
||||
std::string m_close;
|
||||
void strip_whitespace();
|
||||
void process_text(citer beg, citer end);
|
||||
void tokenize(const std::string& tmp);
|
||||
void store_prefixes(std::vector<token>::iterator beg);
|
||||
private:
|
||||
std::vector<token> m_tokens;
|
||||
std::string m_open;
|
||||
std::string m_close;
|
||||
void strip_whitespace();
|
||||
void process_text(citer beg, citer end);
|
||||
void tokenize(const std::string& tmp);
|
||||
void store_prefixes(std::vector<token>::iterator beg);
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace mstch
|
||||
|
@ -4,39 +4,45 @@
|
||||
using namespace mstch;
|
||||
|
||||
token::type token::token_info(char c) {
|
||||
switch (c) {
|
||||
case '>': return type::partial;
|
||||
case '^': return type::inverted_section_open;
|
||||
case '/': return type::section_close;
|
||||
case '&': return type::unescaped_variable;
|
||||
case '#': return type::section_open;
|
||||
case '!': return type::comment;
|
||||
default: return type::variable;
|
||||
}
|
||||
switch (c) {
|
||||
case '>':
|
||||
return type::partial;
|
||||
case '^':
|
||||
return type::inverted_section_open;
|
||||
case '/':
|
||||
return type::section_close;
|
||||
case '&':
|
||||
return type::unescaped_variable;
|
||||
case '#':
|
||||
return type::section_open;
|
||||
case '!':
|
||||
return type::comment;
|
||||
default:
|
||||
return type::variable;
|
||||
}
|
||||
}
|
||||
|
||||
token::token(const std::string& str, std::size_t left, std::size_t right):
|
||||
m_raw(str), m_eol(false), m_ws_only(false)
|
||||
token::token(const std::string& str, std::size_t left, std::size_t right)
|
||||
: m_raw(str), m_eol(false), m_ws_only(false)
|
||||
{
|
||||
if (left != 0 && right != 0) {
|
||||
if (str[left] == '=' && str[str.size() - right - 1] == '=') {
|
||||
m_type = type::delimiter_change;
|
||||
} else if (str[left] == '{' && str[str.size() - right - 1] == '}') {
|
||||
m_type = type::unescaped_variable;
|
||||
m_name = {first_not_ws(str.begin() + left + 1, str.end() - right),
|
||||
first_not_ws(str.rbegin() + 1 + right, str.rend() - left) + 1};
|
||||
if (left != 0 && right != 0) {
|
||||
if (str[left] == '=' && str[str.size() - right - 1] == '=') {
|
||||
m_type = type::delimiter_change;
|
||||
} else if (str[left] == '{' && str[str.size() - right - 1] == '}') {
|
||||
m_type = type::unescaped_variable;
|
||||
m_name = {first_not_ws(str.begin() + left + 1, str.end() - right),
|
||||
first_not_ws(str.rbegin() + 1 + right, str.rend() - left) + 1};
|
||||
} else {
|
||||
auto c = first_not_ws(str.begin() + left, str.end() - right);
|
||||
m_type = token_info(*c);
|
||||
if (m_type != type::variable)
|
||||
c = first_not_ws(c + 1, str.end() - right);
|
||||
m_name = {c, first_not_ws(str.rbegin() + right, str.rend() - left) + 1};
|
||||
m_delims = {{str.begin(), str.begin() + left}, {str.end() - right, str.end()}};
|
||||
}
|
||||
} else {
|
||||
auto c = first_not_ws(str.begin() + left, str.end() - right);
|
||||
m_type = token_info(*c);
|
||||
if (m_type != type::variable)
|
||||
c = first_not_ws(c + 1, str.end() - right);
|
||||
m_name = {c, first_not_ws(str.rbegin() + right, str.rend() - left) + 1};
|
||||
m_delims = {{str.begin(), str.begin() + left},
|
||||
{str.end() - right, str.end()}};
|
||||
m_type = type::text;
|
||||
m_eol = (str.size() > 0 && str[str.size() - 1] == '\n');
|
||||
m_ws_only = (str.find_first_not_of(" \r\n\t") == std::string::npos);
|
||||
}
|
||||
} else {
|
||||
m_type = type::text;
|
||||
m_eol = (str.size() > 0 && str[str.size() - 1] == '\n');
|
||||
m_ws_only = (str.find_first_not_of(" \r\n\t") == std::string::npos);
|
||||
}
|
||||
}
|
||||
|
@ -7,33 +7,40 @@ namespace mstch {
|
||||
using delim_type = std::pair<std::string, std::string>;
|
||||
|
||||
class token {
|
||||
public:
|
||||
enum class type {
|
||||
text, variable, section_open, section_close, inverted_section_open,
|
||||
unescaped_variable, comment, partial, delimiter_change
|
||||
};
|
||||
token(const std::string& str, std::size_t left = 0, std::size_t right = 0);
|
||||
type token_type() const { return m_type; };
|
||||
const std::string& raw() const { return m_raw; };
|
||||
const std::string& name() const { return m_name; };
|
||||
const std::string& partial_prefix() const { return m_partial_prefix; };
|
||||
const delim_type& delims() const { return m_delims; };
|
||||
void partial_prefix(const std::string& p_partial_prefix) {
|
||||
m_partial_prefix = p_partial_prefix;
|
||||
};
|
||||
bool eol() const { return m_eol; }
|
||||
void eol(bool eol) { m_eol = eol; }
|
||||
bool ws_only() const { return m_ws_only; }
|
||||
public:
|
||||
enum class type {
|
||||
text,
|
||||
variable,
|
||||
section_open,
|
||||
section_close,
|
||||
inverted_section_open,
|
||||
unescaped_variable,
|
||||
comment,
|
||||
partial,
|
||||
delimiter_change
|
||||
};
|
||||
token(const std::string& str, std::size_t left = 0, std::size_t right = 0);
|
||||
type token_type() const { return m_type; };
|
||||
const std::string& raw() const { return m_raw; };
|
||||
const std::string& name() const { return m_name; };
|
||||
const std::string& partial_prefix() const { return m_partial_prefix; };
|
||||
const delim_type& delims() const { return m_delims; };
|
||||
void partial_prefix(const std::string& p_partial_prefix) {
|
||||
m_partial_prefix = p_partial_prefix;
|
||||
};
|
||||
bool eol() const { return m_eol; }
|
||||
void eol(bool eol) { m_eol = eol; }
|
||||
bool ws_only() const { return m_ws_only; }
|
||||
|
||||
private:
|
||||
type m_type;
|
||||
std::string m_name;
|
||||
std::string m_raw;
|
||||
std::string m_partial_prefix;
|
||||
delim_type m_delims;
|
||||
bool m_eol;
|
||||
bool m_ws_only;
|
||||
type token_info(char c);
|
||||
private:
|
||||
type m_type;
|
||||
std::string m_name;
|
||||
std::string m_raw;
|
||||
std::string m_partial_prefix;
|
||||
delim_type m_delims;
|
||||
bool m_eol;
|
||||
bool m_ws_only;
|
||||
type token_info(char c);
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace mstch
|
||||
|
@ -2,43 +2,58 @@
|
||||
#include "mstch/mstch.hpp"
|
||||
|
||||
mstch::citer mstch::first_not_ws(mstch::citer begin, mstch::citer end) {
|
||||
for (auto it = begin; it != end; ++it)
|
||||
if (*it != ' ') return it;
|
||||
return end;
|
||||
for (auto it = begin; it != end; ++it)
|
||||
if (*it != ' ')
|
||||
return it;
|
||||
return end;
|
||||
}
|
||||
|
||||
mstch::citer mstch::first_not_ws(mstch::criter begin, mstch::criter end) {
|
||||
for (auto rit = begin; rit != end; ++rit)
|
||||
if (*rit != ' ') return --(rit.base());
|
||||
return --(end.base());
|
||||
for (auto rit = begin; rit != end; ++rit)
|
||||
if (*rit != ' ')
|
||||
return --(rit.base());
|
||||
return --(end.base());
|
||||
}
|
||||
|
||||
mstch::criter mstch::reverse(mstch::citer it) {
|
||||
return std::reverse_iterator<mstch::citer>(it);
|
||||
return std::reverse_iterator<mstch::citer>(it);
|
||||
}
|
||||
|
||||
std::string mstch::html_escape(const std::string& str) {
|
||||
if (mstch::config::escape)
|
||||
return mstch::config::escape(str);
|
||||
if (mstch::config::escape)
|
||||
return mstch::config::escape(str);
|
||||
|
||||
std::string out;
|
||||
citer start = str.begin();
|
||||
std::string out;
|
||||
citer start = str.begin();
|
||||
|
||||
auto add_escape = [&out, &start](const std::string& escaped, citer& it) {
|
||||
out += std::string{start, it} + escaped;
|
||||
start = it + 1;
|
||||
};
|
||||
auto add_escape = [&out, &start](const std::string& escaped, citer& it) {
|
||||
out += std::string{start, it} + escaped;
|
||||
start = it + 1;
|
||||
};
|
||||
|
||||
for (auto it = str.begin(); it != str.end(); ++it)
|
||||
switch (*it) {
|
||||
case '&': add_escape("&", it); break;
|
||||
case '\'': add_escape("'", it); break;
|
||||
case '"': add_escape(""", it); break;
|
||||
case '<': add_escape("<", it); break;
|
||||
case '>': add_escape(">", it); break;
|
||||
case '/': add_escape("/", it); break;
|
||||
default: break;
|
||||
}
|
||||
for (auto it = str.begin(); it != str.end(); ++it)
|
||||
switch (*it) {
|
||||
case '&':
|
||||
add_escape("&", it);
|
||||
break;
|
||||
case '\'':
|
||||
add_escape("'", it);
|
||||
break;
|
||||
case '"':
|
||||
add_escape(""", it);
|
||||
break;
|
||||
case '<':
|
||||
add_escape("<", it);
|
||||
break;
|
||||
case '>':
|
||||
add_escape(">", it);
|
||||
break;
|
||||
case '/':
|
||||
add_escape("/", it);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return out + std::string{start, str.end()};
|
||||
return out + std::string{start, str.end()};
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <variant>
|
||||
|
||||
namespace mstch {
|
||||
|
||||
using citer = std::string::const_iterator;
|
||||
using citer = std::string::const_iterator;
|
||||
using criter = std::string::const_reverse_iterator;
|
||||
|
||||
citer first_not_ws(citer begin, citer end);
|
||||
@ -14,10 +14,8 @@ std::string html_escape(const std::string& str);
|
||||
criter reverse(citer it);
|
||||
|
||||
template<class... Args>
|
||||
auto visit(Args&&... args) -> decltype(boost::apply_visitor(
|
||||
std::forward<Args>(args)...))
|
||||
{
|
||||
return boost::apply_visitor(std::forward<Args>(args)...);
|
||||
auto visit(Args&&... args) -> decltype(std::visit(std::forward<Args>(args)...)) {
|
||||
return std::visit(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace mstch
|
||||
|
@ -1,35 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
|
||||
#include "mstch/mstch.hpp"
|
||||
#include "has_token.hpp"
|
||||
#include "mstch/mstch.hpp"
|
||||
|
||||
namespace mstch {
|
||||
|
||||
class get_token: public boost::static_visitor<const mstch::node&> {
|
||||
public:
|
||||
get_token(const std::string& token, const mstch::node& node):
|
||||
m_token(token), m_node(node)
|
||||
{
|
||||
}
|
||||
class get_token {
|
||||
public:
|
||||
get_token(const std::string& token, const mstch::node& node)
|
||||
: m_token(token), m_node(node)
|
||||
{}
|
||||
|
||||
template<class T>
|
||||
const mstch::node& operator()(const T&) const {
|
||||
return m_node;
|
||||
}
|
||||
template<class T>
|
||||
const mstch::node& operator()(const T&) const {
|
||||
return m_node;
|
||||
}
|
||||
|
||||
const mstch::node& operator()(const map& map) const {
|
||||
return map.at(m_token);
|
||||
}
|
||||
const mstch::node& operator()(const map_wrapper& map) const {
|
||||
return map.values.at(m_token);
|
||||
}
|
||||
|
||||
const mstch::node& operator()(const std::shared_ptr<object>& object) const {
|
||||
return object->at(m_token);
|
||||
}
|
||||
const mstch::node& operator()(const object_wrapper& object) const {
|
||||
return object.values->at(m_token);
|
||||
}
|
||||
|
||||
private:
|
||||
const std::string& m_token;
|
||||
const mstch::node& m_node;
|
||||
private:
|
||||
const std::string& m_token;
|
||||
const mstch::node& m_node;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace mstch
|
||||
|
@ -1,31 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
|
||||
#include "mstch/mstch.hpp"
|
||||
|
||||
namespace mstch {
|
||||
|
||||
class has_token: public boost::static_visitor<bool> {
|
||||
public:
|
||||
has_token(const std::string& token): m_token(token) {
|
||||
}
|
||||
class has_token {
|
||||
public:
|
||||
has_token(const std::string& token) : m_token(token) {}
|
||||
|
||||
template<class T>
|
||||
bool operator()(const T&) const {
|
||||
return m_token == ".";
|
||||
}
|
||||
template<class T>
|
||||
bool operator()(const T&) const {
|
||||
return m_token == ".";
|
||||
}
|
||||
|
||||
bool operator()(const map& map) const {
|
||||
return map.count(m_token) == 1;
|
||||
}
|
||||
bool operator()(const map_wrapper& map) const { return map.values.count(m_token) == 1; }
|
||||
|
||||
bool operator()(const std::shared_ptr<object>& object) const {
|
||||
return object->has(m_token);
|
||||
}
|
||||
bool operator()(const object_wrapper& object) const { return object.values->has(m_token); }
|
||||
|
||||
private:
|
||||
const std::string& m_token;
|
||||
private:
|
||||
const std::string& m_token;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace mstch
|
||||
|
@ -1,41 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
|
||||
#include "mstch/mstch.hpp"
|
||||
|
||||
namespace mstch {
|
||||
|
||||
class is_node_empty: public boost::static_visitor<bool> {
|
||||
public:
|
||||
template<class T>
|
||||
bool operator()(const T&) const {
|
||||
return false;
|
||||
}
|
||||
class is_node_empty {
|
||||
public:
|
||||
template<class T>
|
||||
bool operator()(const T&) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator()(const std::nullptr_t&) const {
|
||||
return true;
|
||||
}
|
||||
bool operator()(const std::nullptr_t&) const { return true; }
|
||||
|
||||
bool operator()(const int& value) const {
|
||||
return value == 0;
|
||||
}
|
||||
bool operator()(const int& value) const { return value == 0; }
|
||||
|
||||
bool operator()(const double& value) const {
|
||||
return value == 0;
|
||||
}
|
||||
bool operator()(const double& value) const { return value == 0; }
|
||||
|
||||
bool operator()(const bool& value) const {
|
||||
return !value;
|
||||
}
|
||||
bool operator()(const bool& value) const { return !value; }
|
||||
|
||||
bool operator()(const std::string& value) const {
|
||||
return value == "";
|
||||
}
|
||||
bool operator()(const std::string& value) const { return value == ""; }
|
||||
|
||||
bool operator()(const array& array) const {
|
||||
return array.size() == 0;
|
||||
}
|
||||
bool operator()(const array_wrapper& array) const { return array.values.size() == 0; }
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace mstch
|
||||
|
@ -1,56 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <sstream>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
|
||||
#include "render_context.hpp"
|
||||
#include "mstch/mstch.hpp"
|
||||
#include "render_context.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
namespace mstch {
|
||||
|
||||
class render_node: public boost::static_visitor<std::string> {
|
||||
public:
|
||||
enum class flag { none, escape_html };
|
||||
render_node(render_context& ctx, flag p_flag = flag::none):
|
||||
m_ctx(ctx), m_flag(p_flag)
|
||||
{
|
||||
}
|
||||
class render_node {
|
||||
public:
|
||||
enum class flag { none, escape_html };
|
||||
render_node(render_context& ctx, flag p_flag = flag::none) : m_ctx(ctx), m_flag(p_flag) {}
|
||||
|
||||
template<class T>
|
||||
std::string operator()(const T&) const {
|
||||
return "";
|
||||
}
|
||||
template<class T>
|
||||
std::string operator()(const T&) const {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string operator()(const int& value) const {
|
||||
return std::to_string(value);
|
||||
}
|
||||
std::string operator()(const int& value) const { return std::to_string(value); }
|
||||
|
||||
std::string operator()(const double& value) const {
|
||||
std::stringstream ss;
|
||||
ss << value;
|
||||
return ss.str();
|
||||
}
|
||||
std::string operator()(const double& value) const {
|
||||
std::stringstream ss;
|
||||
ss << value;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string operator()(const bool& value) const {
|
||||
return value ? "true" : "false";
|
||||
}
|
||||
std::string operator()(const bool& value) const { return value ? "true" : "false"; }
|
||||
|
||||
std::string operator()(const lambda& value) const {
|
||||
template_type interpreted{value([this](const mstch::node& n) {
|
||||
return visit(render_node(m_ctx), n);
|
||||
})};
|
||||
auto rendered = render_context::push(m_ctx).render(interpreted);
|
||||
return (m_flag == flag::escape_html) ? html_escape(rendered) : rendered;
|
||||
}
|
||||
std::string operator()(const lambda_wrapper& value) const {
|
||||
template_type interpreted{value.values(
|
||||
[this](const mstch::node& n) { return visit(render_node(m_ctx), n); })};
|
||||
|
||||
std::string operator()(const std::string& value) const {
|
||||
return (m_flag == flag::escape_html) ? html_escape(value) : value;
|
||||
}
|
||||
auto rendered = render_context::push(m_ctx).render(interpreted);
|
||||
return (m_flag == flag::escape_html) ? html_escape(rendered) : rendered;
|
||||
}
|
||||
|
||||
private:
|
||||
render_context& m_ctx;
|
||||
flag m_flag;
|
||||
std::string operator()(const std::string& value) const {
|
||||
return (m_flag == flag::escape_html) ? html_escape(value) : value;
|
||||
}
|
||||
|
||||
private:
|
||||
render_context& m_ctx;
|
||||
flag m_flag;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace mstch
|
||||
|
@ -1,57 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
|
||||
#include "render_context.hpp"
|
||||
#include "mstch/mstch.hpp"
|
||||
#include "utils.hpp"
|
||||
#include "render_context.hpp"
|
||||
#include "render_node.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
namespace mstch {
|
||||
|
||||
class render_section: public boost::static_visitor<std::string> {
|
||||
public:
|
||||
enum class flag { none, keep_array };
|
||||
render_section(
|
||||
render_context& ctx,
|
||||
const template_type& section,
|
||||
const delim_type& delims,
|
||||
flag p_flag = flag::none):
|
||||
m_ctx(ctx), m_section(section), m_delims(delims), m_flag(p_flag)
|
||||
{
|
||||
}
|
||||
class render_section {
|
||||
public:
|
||||
enum class flag { none, keep_array };
|
||||
render_section(render_context& ctx,
|
||||
const template_type& section,
|
||||
const delim_type& delims,
|
||||
flag p_flag = flag::none)
|
||||
: m_ctx(ctx), m_section(section), m_delims(delims), m_flag(p_flag)
|
||||
{}
|
||||
|
||||
template<class T>
|
||||
std::string operator()(const T& t) const {
|
||||
return render_context::push(m_ctx, t).render(m_section);
|
||||
}
|
||||
template<class T>
|
||||
std::string operator()(const T& t) const {
|
||||
return render_context::push(m_ctx, t).render(m_section);
|
||||
}
|
||||
|
||||
std::string operator()(const lambda& fun) const {
|
||||
std::string section_str;
|
||||
for (auto& token: m_section)
|
||||
section_str += token.raw();
|
||||
template_type interpreted{fun([this](const mstch::node& n) {
|
||||
return visit(render_node(m_ctx), n);
|
||||
}, section_str), m_delims};
|
||||
return render_context::push(m_ctx).render(interpreted);
|
||||
}
|
||||
std::string operator()(const lambda_wrapper& fun) const {
|
||||
std::string section_str;
|
||||
for (auto& token : m_section)
|
||||
section_str += token.raw();
|
||||
template_type interpreted{fun.values(
|
||||
[this](const mstch::node& n) {
|
||||
return visit(render_node(m_ctx), n);
|
||||
},
|
||||
section_str),
|
||||
m_delims};
|
||||
return render_context::push(m_ctx).render(interpreted);
|
||||
}
|
||||
|
||||
std::string operator()(const array& array) const {
|
||||
std::string out;
|
||||
if (m_flag == flag::keep_array)
|
||||
return render_context::push(m_ctx, array).render(m_section);
|
||||
else
|
||||
for (auto& item: array)
|
||||
out += visit(render_section(
|
||||
m_ctx, m_section, m_delims, flag::keep_array), item);
|
||||
return out;
|
||||
}
|
||||
std::string operator()(const array_wrapper& array) const {
|
||||
std::string out;
|
||||
|
||||
private:
|
||||
render_context& m_ctx;
|
||||
const template_type& m_section;
|
||||
const delim_type& m_delims;
|
||||
flag m_flag;
|
||||
if (m_flag == flag::keep_array)
|
||||
return render_context::push(m_ctx, array).render(m_section);
|
||||
|
||||
for (auto& item : array.values)
|
||||
out += visit(render_section(m_ctx, m_section, m_delims, flag::keep_array), item);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
private:
|
||||
render_context& m_ctx;
|
||||
const template_type& m_section;
|
||||
const delim_type& m_delims;
|
||||
flag m_flag;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace mstch
|
||||
|
@ -1,3 +1,2 @@
|
||||
const auto ampersand_escape_data = mstch::map{
|
||||
{"message", std::string{"Some <code>"}}
|
||||
};
|
||||
const mstch::node ampersand_escape_data =
|
||||
mstch::map_wrapper{{{"message", std::string{"Some <code>"}}}};
|
||||
|
@ -1,4 +1,2 @@
|
||||
const auto apostrophe_data = mstch::map{
|
||||
{"apos", std::string{"'"}},
|
||||
{"control", std::string{"X"}}
|
||||
};
|
||||
const mstch::node apostrophe_data =
|
||||
mstch::map_wrapper{{{"apos", std::string{"'"}}, {"control", std::string{"X"}}}};
|
||||
|
@ -1,3 +1,3 @@
|
||||
const auto array_of_strings_data = mstch::map{
|
||||
{"array_of_strings", mstch::array{std::string{"hello"}, std::string{"world"}}}
|
||||
};
|
||||
const mstch::node array_of_strings_data = mstch::map_wrapper{
|
||||
{{"array_of_strings",
|
||||
mstch::array_wrapper{{std::string{"hello"}, std::string{"world"}}}}}};
|
||||
|
@ -1,3 +1 @@
|
||||
const auto backslashes_data = mstch::map{
|
||||
{"value", std::string{"\\abc"}}
|
||||
};
|
||||
const mstch::node backslashes_data = mstch::map_wrapper{{{"value", std::string{"\\abc"}}}};
|
||||
|
@ -1,3 +1,2 @@
|
||||
const auto bug_11_eating_whitespace_data = mstch::map{
|
||||
{"tag", std::string{"yo"}}
|
||||
};
|
||||
const mstch::node bug_11_eating_whitespace_data =
|
||||
mstch::map_wrapper{{{"tag", std::string{"yo"}}}};
|
||||
|
@ -1,3 +1,2 @@
|
||||
const auto bug_length_property_data = mstch::map{
|
||||
{"length", std::string{"hello"}}
|
||||
};
|
||||
const mstch::node bug_length_property_data =
|
||||
mstch::map_wrapper{{{"length", std::string{"hello"}}}};
|
||||
|
@ -1,4 +1,2 @@
|
||||
const mstch::node changing_delimiters_data = mstch::map{
|
||||
{"foo", std::string{"foooooooooooooo"}},
|
||||
{"bar", std::string{"<b>bar!</b>"}}
|
||||
};
|
||||
const mstch::node changing_delimiters_data = mstch::map_wrapper{
|
||||
{{"foo", std::string{"foooooooooooooo"}}, {"bar", std::string{"<b>bar!</b>"}}}};
|
||||
|
@ -1,3 +1,4 @@
|
||||
const mstch::node comments_data = mstch::map{
|
||||
{"title", mstch::lambda{[]()->mstch::node{return std::string{"A Comedy of Errors"};}}}
|
||||
};
|
||||
const mstch::node comments_data =
|
||||
mstch::map_wrapper{{{"title", mstch::lambda_wrapper{{[]() -> mstch::node {
|
||||
return std::string{"A Comedy of Errors"};
|
||||
}}}}}};
|
||||
|
@ -1,69 +1,61 @@
|
||||
class complex_item: public mstch::object {
|
||||
class complex_item : public mstch::object {
|
||||
private:
|
||||
std::string m_name;
|
||||
bool m_current;
|
||||
std::string m_url;
|
||||
std::string m_name;
|
||||
bool m_current;
|
||||
std::string m_url;
|
||||
|
||||
public:
|
||||
complex_item(const std::string& name, bool current, const std::string& url):
|
||||
m_name(name), m_current(current), m_url(url)
|
||||
{
|
||||
register_methods(this, std::map<std::string,mstch::node(complex_item::*)()>{
|
||||
{"name", &complex_item::name}, {"current", &complex_item::current},
|
||||
{"url", &complex_item::url}, {"link", &complex_item::link}
|
||||
});
|
||||
}
|
||||
complex_item(const std::string& name, bool current, const std::string& url)
|
||||
: m_name(name), m_current(current), m_url(url)
|
||||
{
|
||||
register_methods(this,
|
||||
std::map<std::string, mstch::node (complex_item::*)()>{
|
||||
{"name", &complex_item::name},
|
||||
{"current", &complex_item::current},
|
||||
{"url", &complex_item::url},
|
||||
{"link", &complex_item::link}});
|
||||
}
|
||||
|
||||
mstch::node current() {
|
||||
return m_current;
|
||||
}
|
||||
mstch::node current() { return m_current; }
|
||||
|
||||
mstch::node url() {
|
||||
return m_url;
|
||||
}
|
||||
mstch::node url() { return m_url; }
|
||||
|
||||
mstch::node name() {
|
||||
return m_name;
|
||||
}
|
||||
mstch::node name() { return m_name; }
|
||||
|
||||
mstch::node link() {
|
||||
return !m_current;
|
||||
}
|
||||
mstch::node link() { return !m_current; }
|
||||
};
|
||||
|
||||
class complex: public mstch::object {
|
||||
class complex : public mstch::object {
|
||||
private:
|
||||
std::string m_header;
|
||||
mstch::array m_item;
|
||||
std::string m_header;
|
||||
mstch::array m_item;
|
||||
|
||||
public:
|
||||
complex():
|
||||
m_header("Colors"),
|
||||
m_item(mstch::array{
|
||||
std::make_shared<complex_item>("red", true, "#Red"),
|
||||
std::make_shared<complex_item>("green", false, "#Green"),
|
||||
std::make_shared<complex_item>("blue", false, "#Blue")
|
||||
})
|
||||
{
|
||||
register_methods(this, std::map<std::string,mstch::node(complex::*)()>{
|
||||
{"header", &complex::header}, {"item", &complex::item},
|
||||
{"list", &complex::list}, {"empty", &complex::empty}
|
||||
});
|
||||
}
|
||||
complex()
|
||||
: m_header("Colors")
|
||||
, m_item(mstch::array{mstch::object_wrapper{
|
||||
std::make_shared<complex_item>("red", true, "#Red")},
|
||||
mstch::object_wrapper{
|
||||
std::make_shared<complex_item>("green", false, "#Green")},
|
||||
mstch::object_wrapper{std::make_shared<complex_item>("blue",
|
||||
false,
|
||||
"#Blue")}})
|
||||
{
|
||||
register_methods(
|
||||
this,
|
||||
std::map<std::string, mstch::node (complex::*)()>{{"header", &complex::header},
|
||||
{"item", &complex::item},
|
||||
{"list", &complex::list},
|
||||
{"empty", &complex::empty}});
|
||||
}
|
||||
|
||||
mstch::node header() {
|
||||
return m_header;
|
||||
}
|
||||
mstch::node header() { return m_header; }
|
||||
|
||||
mstch::node item() {
|
||||
return m_item;
|
||||
}
|
||||
mstch::node item() { return mstch::array_wrapper{m_item}; }
|
||||
|
||||
mstch::node list() {
|
||||
return m_item.size() != 0;
|
||||
}
|
||||
mstch::node list() { return m_item.size() != 0; }
|
||||
|
||||
mstch::node empty() {
|
||||
return m_item.size() == 0;
|
||||
}
|
||||
mstch::node empty() { return m_item.size() == 0; }
|
||||
};
|
||||
|
||||
const auto complex_data = std::make_shared<complex>();
|
||||
const auto complex_data = mstch::object_wrapper{std::make_shared<complex>()};
|
||||
|
@ -1,8 +1,3 @@
|
||||
const auto context_lookup_data = mstch::map{
|
||||
{"outer", mstch::map{
|
||||
{"id", 1},
|
||||
{"second", mstch::map{
|
||||
{"nothing", 2}
|
||||
}}
|
||||
}}
|
||||
};
|
||||
const mstch::node context_lookup_data = mstch::map_wrapper{
|
||||
{{"outer",
|
||||
mstch::map_wrapper{{{"id", 1}, {"second", mstch::map_wrapper{{{"nothing", 2}}}}}}}}};
|
||||
|
@ -1,6 +1,5 @@
|
||||
const mstch::node delimiters_data = mstch::map{
|
||||
{"first", std::string{"It worked the first time."}},
|
||||
{"second", std::string{"And it worked the second time."}},
|
||||
{"third", std::string{"Then, surprisingly, it worked the third time."}},
|
||||
{"fourth", std::string{"Fourth time also fine!."}}
|
||||
};
|
||||
const mstch::node delimiters_data = mstch::map_wrapper{
|
||||
{{"first", std::string{"It worked the first time."}},
|
||||
{"second", std::string{"And it worked the second time."}},
|
||||
{"third", std::string{"Then, surprisingly, it worked the third time."}},
|
||||
{"fourth", std::string{"Fourth time also fine!."}}}};
|
||||
|
@ -1,4 +1,2 @@
|
||||
const auto disappearing_whitespace_data = mstch::map{
|
||||
{"bedrooms", true},
|
||||
{"total", 1}
|
||||
};
|
||||
const mstch::node disappearing_whitespace_data =
|
||||
mstch::map_wrapper{{{"bedrooms", true}, {"total", 1}}};
|
||||
|
@ -1,34 +1,32 @@
|
||||
class dot_notation_price: public mstch::object {
|
||||
class dot_notation_price : public mstch::object {
|
||||
private:
|
||||
int m_value;
|
||||
mstch::map m_currency;
|
||||
int m_value;
|
||||
mstch::map m_currency;
|
||||
|
||||
public:
|
||||
dot_notation_price():
|
||||
m_value(200), m_currency(mstch::map{{"symbol", std::string{"$"}}, {"name", std::string{"USD"}}})
|
||||
{
|
||||
register_methods(this, std::map<std::string,mstch::node(dot_notation_price::*)()>{
|
||||
{"value", &dot_notation_price::value},
|
||||
{"vat", &dot_notation_price::vat},
|
||||
{"currency", &dot_notation_price::currency}});
|
||||
}
|
||||
dot_notation_price()
|
||||
: m_value(200)
|
||||
, m_currency(mstch::map{{"symbol", std::string{"$"}}, {"name", std::string{"USD"}}})
|
||||
{
|
||||
register_methods(this,
|
||||
std::map<std::string, mstch::node (dot_notation_price::*)()>{
|
||||
{"value", &dot_notation_price::value},
|
||||
{"vat", &dot_notation_price::vat},
|
||||
{"currency", &dot_notation_price::currency}});
|
||||
}
|
||||
|
||||
mstch::node value() {
|
||||
return m_value;
|
||||
}
|
||||
mstch::node value() { return m_value; }
|
||||
|
||||
mstch::node vat() {
|
||||
return m_value * 0.2;
|
||||
}
|
||||
mstch::node vat() { return m_value * 0.2; }
|
||||
|
||||
mstch::node currency() {
|
||||
return m_currency;
|
||||
}
|
||||
mstch::node currency() { return mstch::map_wrapper{m_currency}; }
|
||||
};
|
||||
|
||||
const auto dot_notation_data = mstch::map{
|
||||
{"name", std::string{"A Book"}},
|
||||
{"authors", mstch::array{std::string{"John Power"}, std::string{"Jamie Walsh"}}},
|
||||
{"price", std::make_shared<dot_notation_price>()},
|
||||
{"availability", mstch::map{{"status", true}, {"text", std::string{"In Stock"}}}},
|
||||
{"truthy", mstch::map{{"zero", 0}, {"notTrue", false}}}
|
||||
};
|
||||
const mstch::node dot_notation_data = mstch::map_wrapper{
|
||||
{{"name", std::string{"A Book"}},
|
||||
{"authors",
|
||||
mstch::array_wrapper{{std::string{"John Power"}, std::string{"Jamie Walsh"}}}},
|
||||
{"price", mstch::object_wrapper{std::make_shared<dot_notation_price>()}},
|
||||
{"availability",
|
||||
mstch::map_wrapper{{{"status", true}, {"text", std::string{"In Stock"}}}}},
|
||||
{"truthy", mstch::map_wrapper{{{"zero", 0}, {"notTrue", false}}}}}};
|
||||
|
@ -1,5 +1,2 @@
|
||||
const auto double_render_data = mstch::map{
|
||||
{"foo", true},
|
||||
{"bar", std::string{"{{win}}"}},
|
||||
{"win", std::string{"FAIL"}}
|
||||
};
|
||||
const mstch::node double_render_data = mstch::map_wrapper{
|
||||
{{"foo", true}, {"bar", std::string{"{{win}}"}}, {"win", std::string{"FAIL"}}}};
|
||||
|
@ -1,3 +1 @@
|
||||
const auto empty_list_data = mstch::map{
|
||||
{"jobs", mstch::array{}}
|
||||
};
|
||||
const mstch::node empty_list_data = mstch::map_wrapper{{{"jobs", mstch::array_wrapper{}}}};
|
||||
|
@ -1 +1 @@
|
||||
const auto empty_sections_data = mstch::map{};
|
||||
const mstch::node empty_sections_data = mstch::map_wrapper{{}};
|
||||
|
@ -1,6 +1,5 @@
|
||||
const auto empty_string_data = mstch::map{
|
||||
{"description", std::string{"That is all!"}},
|
||||
{"child", mstch::map{
|
||||
{"description", std::string{""}}
|
||||
}}
|
||||
};
|
||||
#include "mstch/mstch.hpp"
|
||||
|
||||
const auto empty_string_data =
|
||||
mstch::map_wrapper{{{"description", std::string{"That is all!"}},
|
||||
{"child", mstch::map_wrapper{{{"description", std::string{""}}}}}}};
|
||||
|
@ -1 +1 @@
|
||||
const auto empty_template_data = mstch::map{};
|
||||
const mstch::node empty_template_data = mstch::map_wrapper{{}};
|
||||
|
@ -1,3 +1,2 @@
|
||||
const auto error_eof_in_section_data = mstch::map{
|
||||
{"hello", mstch::array{std::string{"a"}, std::string{"b"}}}
|
||||
};
|
||||
const mstch::node error_eof_in_section_data = mstch::map_wrapper{
|
||||
{{"hello", mstch::array_wrapper{{std::string{"a"}, std::string{"b"}}}}}};
|
||||
|
@ -1 +1 @@
|
||||
const auto error_eof_in_tag_data = mstch::map{{"hello", std::string{"world"}}};
|
||||
const mstch::node error_eof_in_tag_data = mstch::map_wrapper{{{"hello", std::string{"world"}}}};
|
||||
|
@ -1,3 +1 @@
|
||||
const auto error_not_found_data = mstch::map{
|
||||
{"bar", 2}
|
||||
};
|
||||
const mstch::node error_not_found_data = mstch::map_wrapper{{{"bar", 2}}};
|
||||
|
@ -1,4 +1,6 @@
|
||||
const mstch::node escaped_data = mstch::map{
|
||||
{"title", mstch::lambda{[]()->mstch::node{ return std::string{"Bear > Shark"}; }}},
|
||||
{"entities", mstch::lambda{[]()->mstch::node{ return std::string{"" \"'<>/"}; }}}
|
||||
};
|
||||
const mstch::node escaped_data = mstch::map_wrapper{
|
||||
{{"title",
|
||||
mstch::lambda_wrapper{{[]() -> mstch::node { return std::string{"Bear > Shark"}; }}}},
|
||||
{"entities", mstch::lambda_wrapper{{[]() -> mstch::node {
|
||||
return std::string{"" \"'<>/"};
|
||||
}}}}}};
|
||||
|
@ -1,6 +1,4 @@
|
||||
const auto falsy_data = mstch::map{
|
||||
{"emptyString", std::string{""}},
|
||||
{"emptyArray", mstch::array{}},
|
||||
{"zero", 0},
|
||||
{"null", mstch::node{}}
|
||||
};
|
||||
const auto falsy_data = mstch::map_wrapper{{{"emptyString", std::string{""}},
|
||||
{"emptyArray", mstch::array_wrapper{}},
|
||||
{"zero", 0},
|
||||
{"null", mstch::node{}}}};
|
||||
|
@ -1,8 +1,7 @@
|
||||
const auto falsy_array_data = mstch::map{
|
||||
{"list", mstch::array{
|
||||
mstch::array{std::string{""}, std::string{"emptyString"}},
|
||||
mstch::array{mstch::array{}, std::string{"emptyArray"}},
|
||||
mstch::array{0, std::string{"zero"}},
|
||||
mstch::array{mstch::node{}, std::string{"null"}}}
|
||||
}
|
||||
};
|
||||
const auto falsy_array_data = mstch::map_wrapper{
|
||||
{{"list",
|
||||
mstch::array_wrapper{
|
||||
{mstch::array_wrapper{{std::string{""}, std::string{"emptyString"}}},
|
||||
mstch::array_wrapper{{mstch::array_wrapper{}, std::string{"emptyArray"}}},
|
||||
mstch::array_wrapper{{0, std::string{"zero"}}},
|
||||
mstch::array_wrapper{{mstch::node{}, std::string{"null"}}}}}}}};
|
||||
|
@ -1,19 +1,22 @@
|
||||
const auto grandparent_context_data = mstch::map{
|
||||
{"grand_parent_id", std::string{"grand_parent1"}},
|
||||
{"parent_contexts", mstch::array{
|
||||
mstch::map{
|
||||
{"parent_id", std::string{"parent1"}},
|
||||
{"child_contexts", mstch::array{
|
||||
mstch::map{{"child_id", std::string{"parent1-child1"}}},
|
||||
mstch::map{{"child_id", std::string{"parent1-child2"}}}
|
||||
}}
|
||||
},
|
||||
mstch::map{
|
||||
{"parent_id", std::string{"parent2"}},
|
||||
{"child_contexts", mstch::array{
|
||||
mstch::map{{"child_id", std::string{"parent2-child1"}}},
|
||||
mstch::map{{"child_id", std::string{"parent2-child2"}}}
|
||||
}}
|
||||
}
|
||||
}}
|
||||
};
|
||||
const auto grandparent_context_data = mstch::map_wrapper{
|
||||
{{"grand_parent_id", std::string{"grand_parent1"}},
|
||||
{"parent_contexts",
|
||||
mstch::array_wrapper{
|
||||
{mstch::map_wrapper{
|
||||
{{"parent_id", std::string{"parent1"}},
|
||||
{"child_contexts",
|
||||
mstch::array_wrapper{
|
||||
{mstch::map_wrapper{
|
||||
{{"child_id", std::string{"parent1-child1"}}}},
|
||||
mstch::map_wrapper{
|
||||
{{"child_id",
|
||||
std::string{"parent1-child2"}}}}}}}}},
|
||||
mstch::map_wrapper{
|
||||
{{"parent_id", std::string{"parent2"}},
|
||||
{"child_contexts",
|
||||
mstch::array_wrapper{
|
||||
{mstch::map_wrapper{
|
||||
{{"child_id", std::string{"parent2-child1"}}}},
|
||||
mstch::map_wrapper{
|
||||
{{"child_id",
|
||||
std::string{"parent2-child2"}}}}}}}}}}}}}};
|
||||
|
@ -1,28 +1,26 @@
|
||||
class higher_order_sections: public mstch::object {
|
||||
private:
|
||||
std::string m_helper;
|
||||
public:
|
||||
higher_order_sections(): m_helper("To tinker?") {
|
||||
register_methods(this, std::map<std::string,mstch::node(higher_order_sections::*)()>{
|
||||
{"name", &higher_order_sections::name},
|
||||
{"helper", &higher_order_sections::helper},
|
||||
{"bolder", &higher_order_sections::bolder}
|
||||
});
|
||||
}
|
||||
class higher_order_sections : public mstch::object {
|
||||
private:
|
||||
std::string m_helper;
|
||||
|
||||
mstch::node name() {
|
||||
return std::string{"Tater"};
|
||||
}
|
||||
public:
|
||||
higher_order_sections() : m_helper("To tinker?") {
|
||||
register_methods(this,
|
||||
std::map<std::string, mstch::node (higher_order_sections::*)()>{
|
||||
{"name", &higher_order_sections::name},
|
||||
{"helper", &higher_order_sections::helper},
|
||||
{"bolder", &higher_order_sections::bolder}});
|
||||
}
|
||||
|
||||
mstch::node helper() {
|
||||
return m_helper;
|
||||
}
|
||||
mstch::node name() { return std::string{"Tater"}; }
|
||||
|
||||
mstch::node bolder() {
|
||||
return mstch::lambda{[this](const std::string& text) -> mstch::node {
|
||||
return "<b>" + text + "</b> " + m_helper;
|
||||
}};
|
||||
}
|
||||
mstch::node helper() { return m_helper; }
|
||||
|
||||
mstch::node bolder() {
|
||||
return mstch::lambda_wrapper{{[this](const std::string& text) -> mstch::node {
|
||||
return "<b>" + text + "</b> " + m_helper;
|
||||
}}};
|
||||
}
|
||||
};
|
||||
|
||||
const mstch::node higher_order_sections_data = std::make_shared<higher_order_sections>();
|
||||
const mstch::node higher_order_sections_data =
|
||||
mstch::object_wrapper{std::make_shared<higher_order_sections>()};
|
||||
|
@ -1,8 +1,5 @@
|
||||
const auto implicit_iterator_data = mstch::map{
|
||||
{"data", mstch::map{
|
||||
{"author", mstch::map{
|
||||
{"twitter_id", 819606},
|
||||
{"name", std::string{"janl"}}
|
||||
}}
|
||||
}}
|
||||
};
|
||||
const auto implicit_iterator_data = mstch::map_wrapper{
|
||||
{{"data",
|
||||
mstch::map_wrapper{{{"author",
|
||||
mstch::map_wrapper{{{"twitter_id", 819606},
|
||||
{"name", std::string{"janl"}}}}}}}}}};
|
||||
|
@ -1,3 +1,2 @@
|
||||
const auto included_tag_data = mstch::map{
|
||||
{"html", std::string{"I like {{mustache}}"}}
|
||||
};
|
||||
const mstch::node included_tag_data =
|
||||
mstch::map_wrapper{{{"html", std::string{"I like {{mustache}}"}}}};
|
||||
|
@ -1,3 +1 @@
|
||||
const auto inverted_section_data = mstch::map{
|
||||
{"repos", mstch::array{}}
|
||||
};
|
||||
const auto inverted_section_data = mstch::map_wrapper{{{"repos", mstch::array_wrapper{}}}};
|
||||
|
@ -1,5 +1,2 @@
|
||||
const auto keys_with_questionmarks_data = mstch::map{
|
||||
{"person?", mstch::map{
|
||||
{"name", std::string{"Jon"}}
|
||||
}}
|
||||
};
|
||||
const auto keys_with_questionmarks_data =
|
||||
mstch::map_wrapper{{{"person?", mstch::map_wrapper{{{"name", std::string{"Jon"}}}}}}};
|
||||
|
@ -1 +1 @@
|
||||
const auto multiline_comment_data = mstch::map{};
|
||||
const mstch::node multiline_comment_data = mstch::map_wrapper{{}};
|
||||
|
@ -1 +1 @@
|
||||
const auto nested_dot_data = mstch::map{{"name", std::string{"Bruno"}}};
|
||||
const mstch::node nested_dot_data = mstch::map_wrapper{{{"name", std::string{"Bruno"}}}};
|
||||
|
@ -1,6 +1,5 @@
|
||||
const mstch::node nested_higher_order_sections_data = mstch::map{
|
||||
{"bold", mstch::lambda{[](const std::string& text) -> mstch::node {
|
||||
return std::string{"<b>"} + text + std::string{"</b>"};
|
||||
}}},
|
||||
{"person", mstch::map{{"name", std::string{"Jonas"}}}}
|
||||
};
|
||||
const mstch::node nested_higher_order_sections_data = mstch::map_wrapper{
|
||||
{{"bold", mstch::lambda_wrapper{{[](const std::string& text) -> mstch::node {
|
||||
return std::string{"<b>"} + text + std::string{"</b>"};
|
||||
}}}},
|
||||
{"person", mstch::map_wrapper{{{"name", std::string{"Jonas"}}}}}}};
|
||||
|
@ -1,8 +1,7 @@
|
||||
const auto nested_iterating_data = mstch::map{
|
||||
{"inner", mstch::array{mstch::map{
|
||||
{"foo", std::string{"foo"}},
|
||||
{"inner", mstch::array{mstch::map{
|
||||
{"bar", std::string{"bar"}}
|
||||
}}}
|
||||
}}}
|
||||
};
|
||||
const mstch::node nested_iterating_data = mstch::map_wrapper{
|
||||
{{"inner",
|
||||
mstch::array_wrapper{
|
||||
{mstch::map_wrapper{{{"foo", std::string{"foo"}},
|
||||
{"inner",
|
||||
mstch::array_wrapper{{mstch::map_wrapper{
|
||||
{{"bar", std::string{"bar"}}}}}}}}}}}}}};
|
||||
|
@ -1,7 +1,6 @@
|
||||
const auto nesting_data = mstch::map{
|
||||
{"foo", mstch::array{
|
||||
mstch::map{{"a", mstch::map{{"b", 1}}}},
|
||||
mstch::map{{"a", mstch::map{{"b", 2}}}},
|
||||
mstch::map{{"a", mstch::map{{"b", 3}}}}
|
||||
}}
|
||||
};
|
||||
const mstch::node nesting_data = mstch::map_wrapper{
|
||||
{{"foo",
|
||||
mstch::array_wrapper{
|
||||
{mstch::map_wrapper{{{"a", mstch::map_wrapper{{{"b", 1}}}}}},
|
||||
mstch::map_wrapper{{{"a", mstch::map_wrapper{{{"b", 2}}}}}},
|
||||
mstch::map_wrapper{{{"a", mstch::map_wrapper{{{"b", 3}}}}}}}}}}};
|
||||
|
@ -1,8 +1,5 @@
|
||||
const auto nesting_same_name_data = mstch::map{
|
||||
{"items", mstch::array{
|
||||
mstch::map{
|
||||
{"name", std::string{"name"}},
|
||||
{"items", mstch::array{1, 2, 3, 4}}
|
||||
}
|
||||
}}
|
||||
};
|
||||
const mstch::node nesting_same_name_data = mstch::map_wrapper{
|
||||
{{"items",
|
||||
mstch::array_wrapper{
|
||||
{mstch::map_wrapper{{{"name", std::string{"name"}},
|
||||
{"items", mstch::array_wrapper{{1, 2, 3, 4}}}}}}}}}};
|
||||
|
@ -1,8 +1,8 @@
|
||||
const auto null_lookup_array_data = mstch::map{
|
||||
{"name", std::string{"David"}},
|
||||
{"twitter", std::string{"@dasilvacontin"}},
|
||||
{"farray", mstch::array{
|
||||
mstch::array{std::string{"Flor"}, std::string{"@florrts"}},
|
||||
mstch::array{std::string{"Miquel"}, mstch::node{}},
|
||||
}}
|
||||
};
|
||||
const mstch::node null_lookup_array_data = mstch::map_wrapper{
|
||||
{{"name", std::string{"David"}},
|
||||
{"twitter", std::string{"@dasilvacontin"}},
|
||||
{"farray",
|
||||
mstch::array_wrapper{{
|
||||
mstch::array_wrapper{{std::string{"Flor"}, std::string{"@florrts"}}},
|
||||
mstch::array_wrapper{{std::string{"Miquel"}, mstch::node{}}},
|
||||
}}}}};
|
||||
|
@ -1,14 +1,8 @@
|
||||
const auto null_lookup_object_data = mstch::map{
|
||||
{"name", std::string{"David"}},
|
||||
{"twitter", std::string{"@dasilvacontin"}},
|
||||
{"fobject", mstch::array{
|
||||
mstch::map{
|
||||
{"name", std::string{"Flor"}},
|
||||
{"twitter", std::string{"@florrts"}}
|
||||
},
|
||||
mstch::map{
|
||||
{"name", std::string{"Miquel"}},
|
||||
{"twitter", mstch::node{}}
|
||||
}
|
||||
}}
|
||||
};
|
||||
const mstch::node null_lookup_object_data = mstch::map_wrapper{
|
||||
{{"name", std::string{"David"}},
|
||||
{"twitter", std::string{"@dasilvacontin"}},
|
||||
{"fobject",
|
||||
mstch::array_wrapper{{{mstch::map_wrapper{{{"name", std::string{"Flor"}},
|
||||
{"twitter", std::string{"@florrts"}}}}},
|
||||
mstch::map_wrapper{{{"name", std::string{"Miquel"}},
|
||||
{"twitter", mstch::node{}}}}}}}}};
|
||||
|
@ -1,6 +1,4 @@
|
||||
const auto null_string_data = mstch::map{
|
||||
{"name", std::string{"Elise"}},
|
||||
{"glytch", true},
|
||||
{"binary", false},
|
||||
{"value", mstch::node{}}
|
||||
};
|
||||
const mstch::node null_string_data = mstch::map_wrapper{{{"name", std::string{"Elise"}},
|
||||
{"glytch", true},
|
||||
{"binary", false},
|
||||
{"value", mstch::node{}}}};
|
||||
|
@ -1,4 +1,2 @@
|
||||
const auto null_view_data = mstch::map{
|
||||
{"name", std::string{"Joe"}},
|
||||
{"friends", mstch::node{}}
|
||||
};
|
||||
const mstch::node null_view_data =
|
||||
mstch::map_wrapper{{{"name", std::string{"Joe"}}, {"friends", mstch::node{}}}};
|
||||
|
@ -1,3 +1,4 @@
|
||||
const auto partial_array_data = mstch::map{
|
||||
{"array", mstch::array{std::string{"1"}, std::string{"2"}, std::string{"3"}, std::string{"4"}}}
|
||||
};
|
||||
const mstch::node partial_array_data = mstch::map_wrapper{
|
||||
{{"array",
|
||||
mstch::array_wrapper{
|
||||
{std::string{"1"}, std::string{"2"}, std::string{"3"}, std::string{"4"}}}}}};
|
||||
|
@ -1,8 +1,6 @@
|
||||
const auto partial_array_of_partials_data = mstch::map{
|
||||
{"numbers", mstch::array{
|
||||
mstch::map{{"i", std::string{"1"}}},
|
||||
mstch::map{{"i", std::string{"2"}}},
|
||||
mstch::map{{"i", std::string{"3"}}},
|
||||
mstch::map{{"i", std::string{"4"}}}
|
||||
}}
|
||||
};
|
||||
const mstch::node partial_array_of_partials_data = mstch::map_wrapper{
|
||||
{{"numbers",
|
||||
mstch::array_wrapper{{mstch::map_wrapper{{{"i", std::string{"1"}}}},
|
||||
mstch::map_wrapper{{{"i", std::string{"2"}}}},
|
||||
mstch::map_wrapper{{{"i", std::string{"3"}}}},
|
||||
mstch::map_wrapper{{{"i", std::string{"4"}}}}}}}}};
|
||||
|
@ -1,3 +1,4 @@
|
||||
const auto partial_array_of_partials_implicit_data = mstch::map{
|
||||
{"numbers", mstch::array{std::string{"1"}, std::string{"2"}, std::string{"3"}, std::string{"4"}}}
|
||||
};
|
||||
const mstch::node partial_array_of_partials_implicit_data = mstch::map_wrapper{
|
||||
{{"numbers",
|
||||
mstch::array_wrapper{
|
||||
{std::string{"1"}, std::string{"2"}, std::string{"3"}, std::string{"4"}}}}}};
|
||||
|
@ -1,3 +1 @@
|
||||
const auto partial_empty_data = mstch::map{
|
||||
{"foo", 1}
|
||||
};
|
||||
const mstch::node partial_empty_data = mstch::map_wrapper{{{"foo", 1}}};
|
||||
|
@ -1,4 +1,6 @@
|
||||
const mstch::node partial_template_data = mstch::map{
|
||||
{"title", mstch::lambda{[]()->mstch::node{ return std::string{"Welcome"}; }}},
|
||||
{"again", mstch::lambda{[]()->mstch::node{ return std::string{"Goodbye"}; }}},
|
||||
};
|
||||
const mstch::node partial_template_data = mstch::map_wrapper{{
|
||||
{"title",
|
||||
mstch::lambda_wrapper{{[]() -> mstch::node { return std::string{"Welcome"}; }}}},
|
||||
{"again",
|
||||
mstch::lambda_wrapper{{[]() -> mstch::node { return std::string{"Goodbye"}; }}}},
|
||||
}};
|
||||
|
@ -39,4 +39,4 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
const auto partial_view_data = std::make_shared<partial_view>();
|
||||
const mstch::node partial_view_data = mstch::object_wrapper{std::make_shared<partial_view>()};
|
||||
|
@ -1,41 +1,31 @@
|
||||
class partial_whitespace: public mstch::object {
|
||||
class partial_whitespace : public mstch::object {
|
||||
private:
|
||||
int m_value;
|
||||
int m_value;
|
||||
|
||||
public:
|
||||
partial_whitespace(): m_value(10000) {
|
||||
register_methods(this, std::map<std::string,mstch::node(partial_whitespace::*)()>{
|
||||
{"greeting", &partial_whitespace::greeting},
|
||||
{"farewell", &partial_whitespace::farewell},
|
||||
{"name", &partial_whitespace::name},
|
||||
{"value", &partial_whitespace::value},
|
||||
{"taxed_value", &partial_whitespace::taxed_value},
|
||||
{"in_ca", &partial_whitespace::in_ca}
|
||||
});
|
||||
}
|
||||
partial_whitespace() : m_value(10000) {
|
||||
register_methods(this,
|
||||
std::map<std::string, mstch::node (partial_whitespace::*)()>{
|
||||
{"greeting", &partial_whitespace::greeting},
|
||||
{"farewell", &partial_whitespace::farewell},
|
||||
{"name", &partial_whitespace::name},
|
||||
{"value", &partial_whitespace::value},
|
||||
{"taxed_value", &partial_whitespace::taxed_value},
|
||||
{"in_ca", &partial_whitespace::in_ca}});
|
||||
}
|
||||
|
||||
mstch::node greeting() {
|
||||
return std::string{"Welcome"};
|
||||
}
|
||||
mstch::node greeting() { return std::string{"Welcome"}; }
|
||||
|
||||
mstch::node farewell() {
|
||||
return std::string{"Fair enough, right?"};
|
||||
}
|
||||
mstch::node farewell() { return std::string{"Fair enough, right?"}; }
|
||||
|
||||
mstch::node name() {
|
||||
return std::string{"Chris"};
|
||||
}
|
||||
mstch::node name() { return std::string{"Chris"}; }
|
||||
|
||||
mstch::node value() {
|
||||
return m_value;
|
||||
}
|
||||
mstch::node value() { return m_value; }
|
||||
|
||||
mstch::node taxed_value() {
|
||||
return static_cast<int>(m_value - (m_value * 0.4));
|
||||
}
|
||||
mstch::node taxed_value() { return static_cast<int>(m_value - (m_value * 0.4)); }
|
||||
|
||||
mstch::node in_ca() {
|
||||
return true;
|
||||
}
|
||||
mstch::node in_ca() { return true; }
|
||||
};
|
||||
|
||||
const auto partial_whitespace_data = std::make_shared<partial_whitespace>();
|
||||
const mstch::node partial_whitespace_data =
|
||||
mstch::object_wrapper{std::make_shared<partial_whitespace>()};
|
||||
|
@ -1,8 +1,7 @@
|
||||
const auto recursion_with_same_names_data = mstch::map{
|
||||
{"name", std::string{"name"}},
|
||||
{"description", std::string{"desc"}},
|
||||
{"terms", mstch::array{
|
||||
mstch::map{{"name", std::string{"t1"}}, {"index", 0}},
|
||||
mstch::map{{"name", std::string{"t2"}}, {"index", 1}}
|
||||
}}
|
||||
};
|
||||
const mstch::node recursion_with_same_names_data = mstch::map_wrapper{
|
||||
{{"name", std::string{"name"}},
|
||||
{"description", std::string{"desc"}},
|
||||
{"terms",
|
||||
mstch::array_wrapper{
|
||||
{mstch::map_wrapper{{{"name", std::string{"t1"}}, {"index", 0}}},
|
||||
mstch::map_wrapper{{{"name", std::string{"t2"}}, {"index", 1}}}}}}}};
|
||||
|
@ -1,6 +1,5 @@
|
||||
const auto reuse_of_enumerables_data = mstch::map{
|
||||
{"terms", mstch::array{
|
||||
mstch::map{{"name", std::string{"t1"}}, {"index", 0}},
|
||||
mstch::map{{"name", std::string{"t2"}}, {"index", 1}}
|
||||
}}
|
||||
};
|
||||
const mstch::node reuse_of_enumerables_data = mstch::map_wrapper{
|
||||
{{"terms",
|
||||
mstch::array_wrapper{
|
||||
{mstch::map_wrapper{{{"name", std::string{"t1"}}, {"index", 0}}},
|
||||
mstch::map_wrapper{{{"name", std::string{"t2"}}, {"index", 1}}}}}}}};
|
||||
|
@ -1,10 +1,9 @@
|
||||
const auto section_as_context_data = mstch::map{
|
||||
{"a_object", mstch::map{
|
||||
{"title", std::string{"this is an object"}},
|
||||
{"description", std::string{"one of its attributes is a list"}},
|
||||
{"a_list", mstch::array{
|
||||
mstch::map{{"label", std::string{"listitem1"}}},
|
||||
mstch::map{{"label", std::string{"listitem2"}}}
|
||||
}}
|
||||
}}
|
||||
};
|
||||
const mstch::node section_as_context_data = mstch::map_wrapper{
|
||||
{{"a_object",
|
||||
mstch::map_wrapper{
|
||||
{{"title", std::string{"this is an object"}},
|
||||
{"description", std::string{"one of its attributes is a list"}},
|
||||
{"a_list",
|
||||
mstch::array_wrapper{
|
||||
{mstch::map_wrapper{{{"label", std::string{"listitem1"}}}},
|
||||
mstch::map_wrapper{{{"label", std::string{"listitem2"}}}}}}}}}}}};
|
||||
|
@ -1,5 +1,4 @@
|
||||
const mstch::node section_functions_in_partials_data = mstch::map{
|
||||
{"bold", mstch::lambda{[](const std::string& text) -> mstch::node {
|
||||
return std::string{"<b>"} + text + std::string{"</b>"};
|
||||
}}}
|
||||
};
|
||||
const mstch::node section_functions_in_partials_data = mstch::map_wrapper{
|
||||
{{"bold", mstch::lambda_wrapper{{[](const std::string& text) -> mstch::node {
|
||||
return std::string{"<b>"} + text + std::string{"</b>"};
|
||||
}}}}}};
|
||||
|
@ -29,4 +29,4 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
const auto simple_data = std::make_shared<simple>();
|
||||
const mstch::node simple_data = mstch::object_wrapper{std::make_shared<simple>()};
|
||||
|
@ -1,4 +1,4 @@
|
||||
const auto string_as_context_data = mstch::map{
|
||||
{"a_string", std::string{"aa"}},
|
||||
{"a_list", mstch::array{std::string{"a"},std::string{"b"},std::string{"c"}}}
|
||||
};
|
||||
const mstch::node string_as_context_data = mstch::map_wrapper{
|
||||
{{"a_string", std::string{"aa"}},
|
||||
{"a_list",
|
||||
mstch::array_wrapper{{std::string{"a"}, std::string{"b"}, std::string{"c"}}}}}};
|
||||
|
@ -1,4 +1,2 @@
|
||||
const auto two_in_a_row_data = mstch::map{
|
||||
{"name", std::string{"Joe"}},
|
||||
{"greeting", std::string{"Welcome"}}
|
||||
};
|
||||
const mstch::node two_in_a_row_data = mstch::map_wrapper{
|
||||
{{"name", std::string{"Joe"}}, {"greeting", std::string{"Welcome"}}}};
|
||||
|
@ -1 +1 @@
|
||||
const auto two_sections_data = mstch::map{};
|
||||
const mstch::node two_sections_data = mstch::map_wrapper{{}};
|
||||
|
@ -1,3 +1,4 @@
|
||||
const mstch::node unescaped_data = mstch::map{
|
||||
{"title", mstch::lambda{[]()->mstch::node{ return std::string{"Bear > Shark"}; }}}
|
||||
};
|
||||
const mstch::node unescaped_data =
|
||||
mstch::map_wrapper{{{"title", mstch::lambda_wrapper{{[]() -> mstch::node {
|
||||
return std::string{"Bear > Shark"};
|
||||
}}}}}};
|
||||
|
@ -1,4 +1,2 @@
|
||||
const auto whitespace_data = mstch::map{
|
||||
{"tag1", std::string{"Hello"}},
|
||||
{"tag2", std::string{"World"}}
|
||||
};
|
||||
const mstch::node whitespace_data =
|
||||
mstch::map_wrapper{{{"tag1", std::string{"Hello"}}, {"tag2", std::string{"World"}}}};
|
||||
|
@ -1 +1,2 @@
|
||||
const auto zero_view_data = mstch::map{{"nums", mstch::array{0, 1, 2}}};
|
||||
const mstch::node zero_view_data =
|
||||
mstch::map_wrapper{{{"nums", mstch::array_wrapper{{0, 1, 2}}}}};
|
||||
|
@ -1,32 +1,36 @@
|
||||
std::map<std::string,mstch::node> specs_lambdas {
|
||||
{"Interpolation", mstch::lambda{[](const std::string&) -> mstch::node {
|
||||
return std::string{"world"};
|
||||
}}},
|
||||
{"Interpolation - Expansion", mstch::lambda{[](const std::string&) -> mstch::node {
|
||||
return std::string{"{{planet}}"};
|
||||
}}},
|
||||
{"Interpolation - Alternate Delimiters", mstch::lambda{[](const std::string&) -> mstch::node {
|
||||
return std::string{"|planet| => {{planet}}"};
|
||||
}}},
|
||||
{"Interpolation - Multiple Calls", mstch::lambda{[](const std::string&) -> mstch::node {
|
||||
static int calls = 0; return ++calls;
|
||||
}}},
|
||||
{"Escaping", mstch::lambda{[](const std::string&) -> mstch::node {
|
||||
return std::string{">"};
|
||||
}}},
|
||||
{"Section", mstch::lambda{[](const std::string& txt) -> mstch::node {
|
||||
return std::string{(txt == "{{x}}") ? "yes" : "no"};
|
||||
}}},
|
||||
{"Section - Expansion", mstch::lambda{[](const std::string& txt) -> mstch::node {
|
||||
return txt + std::string{"{{planet}}"} + txt;
|
||||
}}},
|
||||
{"Section - Alternate Delimiters", mstch::lambda{[](const std::string& txt) -> mstch::node {
|
||||
return txt + std::string{"{{planet}} => |planet|"} + txt;
|
||||
}}},
|
||||
{"Section - Multiple Calls", mstch::lambda{[](const std::string& txt) -> mstch::node {
|
||||
return "__" + txt + "__";
|
||||
}}},
|
||||
{"Inverted Section", mstch::lambda{[](const std::string&) -> mstch::node {
|
||||
return false;
|
||||
}}}
|
||||
};
|
||||
std::map<std::string, mstch::node> specs_lambdas{
|
||||
{"Interpolation", mstch::lambda_wrapper{{[](const std::string&) -> mstch::node {
|
||||
return std::string{"world"};
|
||||
}}}},
|
||||
{"Interpolation - Expansion",
|
||||
mstch::lambda_wrapper{{[](const std::string&) -> mstch::node {
|
||||
return std::string{"{{planet}}"};
|
||||
}}}},
|
||||
{"Interpolation - Alternate Delimiters",
|
||||
mstch::lambda_wrapper{{[](const std::string&) -> mstch::node {
|
||||
return std::string{"|planet| => {{planet}}"};
|
||||
}}}},
|
||||
{"Interpolation - Multiple Calls",
|
||||
mstch::lambda_wrapper{{[](const std::string&) -> mstch::node {
|
||||
static int calls = 0;
|
||||
return ++calls;
|
||||
}}}},
|
||||
{"Escaping", mstch::lambda_wrapper{{[](const std::string&) -> mstch::node {
|
||||
return std::string{">"};
|
||||
}}}},
|
||||
{"Section", mstch::lambda_wrapper{{[](const std::string& txt) -> mstch::node {
|
||||
return std::string{(txt == "{{x}}") ? "yes" : "no"};
|
||||
}}}},
|
||||
{"Section - Expansion",
|
||||
mstch::lambda_wrapper{{[](const std::string& txt) -> mstch::node {
|
||||
return txt + std::string{"{{planet}}"} + txt;
|
||||
}}}},
|
||||
{"Section - Alternate Delimiters",
|
||||
mstch::lambda_wrapper{{[](const std::string& txt) -> mstch::node {
|
||||
return txt + std::string{"{{planet}} => |planet|"} + txt;
|
||||
}}}},
|
||||
{"Section - Multiple Calls",
|
||||
mstch::lambda_wrapper{
|
||||
{[](const std::string& txt) -> mstch::node { return "__" + txt + "__"; }}}},
|
||||
{"Inverted Section",
|
||||
mstch::lambda_wrapper{{[](const std::string&) -> mstch::node { return false; }}}}};
|
||||
|
@ -1,91 +1,99 @@
|
||||
#define CATCH_CONFIG_MAIN
|
||||
|
||||
#include "catch.hpp"
|
||||
#include "rapidjson/document.h"
|
||||
#include "mstch/mstch.hpp"
|
||||
#include "test_context.hpp"
|
||||
#include "test_data.hpp"
|
||||
#include "rapidjson/document.h"
|
||||
#include "specs_data.hpp"
|
||||
#include "specs_lambdas.hpp"
|
||||
#include "test_context.hpp"
|
||||
#include "test_data.hpp"
|
||||
|
||||
using namespace mstchtest;
|
||||
|
||||
mstch::node to_value(const rapidjson::Value& val) {
|
||||
if (val.IsString())
|
||||
return std::string{val.GetString()};
|
||||
if (val.IsBool())
|
||||
return val.GetBool();
|
||||
if (val.IsDouble())
|
||||
return val.GetDouble();
|
||||
if (val.IsInt())
|
||||
return val.GetInt();
|
||||
return mstch::node{};
|
||||
if (val.IsString())
|
||||
return std::string{val.GetString()};
|
||||
if (val.IsBool())
|
||||
return val.GetBool();
|
||||
if (val.IsDouble())
|
||||
return val.GetDouble();
|
||||
if (val.IsInt())
|
||||
return val.GetInt();
|
||||
return mstch::node{};
|
||||
}
|
||||
|
||||
mstch::array to_array(const rapidjson::Value& val);
|
||||
|
||||
mstch::map to_object(const rapidjson::Value& val) {
|
||||
mstch::map ret;
|
||||
for (auto i = val.MemberBegin(); i != val.MemberEnd(); ++i) {
|
||||
if (i->value.IsArray())
|
||||
ret.insert(std::make_pair(i->name.GetString(), to_array(i->value)));
|
||||
else if (i->value.IsObject())
|
||||
ret.insert(std::make_pair(i->name.GetString(), to_object(i->value)));
|
||||
else
|
||||
ret.insert(std::make_pair(i->name.GetString(), to_value(i->value)));
|
||||
}
|
||||
return ret;
|
||||
mstch::map ret;
|
||||
for (auto i = val.MemberBegin(); i != val.MemberEnd(); ++i) {
|
||||
if (i->value.IsArray())
|
||||
ret.insert(std::make_pair(i->name.GetString(),
|
||||
mstch::array_wrapper{to_array(i->value)}));
|
||||
else if (i->value.IsObject())
|
||||
ret.insert(std::make_pair(i->name.GetString(),
|
||||
mstch::map_wrapper{to_object(i->value)}));
|
||||
else
|
||||
ret.insert(std::make_pair(i->name.GetString(), to_value(i->value)));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
mstch::array to_array(const rapidjson::Value& val) {
|
||||
mstch::array ret;
|
||||
for (auto i = val.Begin(); i != val.End(); ++i) {
|
||||
if (i->IsArray())
|
||||
ret.push_back(to_array(*i));
|
||||
else if (i->IsObject())
|
||||
ret.push_back(to_object(*i));
|
||||
else
|
||||
ret.push_back(to_value(*i));
|
||||
}
|
||||
return ret;
|
||||
mstch::array ret;
|
||||
for (auto i = val.Begin(); i != val.End(); ++i) {
|
||||
if (i->IsArray())
|
||||
ret.push_back(mstch::array_wrapper{to_array(*i)});
|
||||
else if (i->IsObject())
|
||||
ret.push_back(mstch::map_wrapper{to_object(*i)});
|
||||
else
|
||||
ret.push_back(to_value(*i));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
mstch::node parse_with_rapidjson(const std::string& str) {
|
||||
rapidjson::Document doc;
|
||||
doc.Parse(str.c_str());
|
||||
return to_object(doc);
|
||||
rapidjson::Document doc;
|
||||
doc.Parse(str.c_str());
|
||||
return mstch::map_wrapper{to_object(doc)};
|
||||
}
|
||||
|
||||
#define MSTCH_PARTIAL_TEST(x) TEST_CASE(#x) { \
|
||||
REQUIRE(x ## _txt == mstch::render(x ## _mustache, x ## _data, {{"partial", x ## _partial}})); \
|
||||
}
|
||||
#define MSTCH_PARTIAL_TEST(x) \
|
||||
TEST_CASE(#x) { \
|
||||
REQUIRE(x##_txt == mstch::render(x##_mustache, x##_data, {{"partial", x##_partial}})); \
|
||||
}
|
||||
|
||||
#define MSTCH_TEST(x) TEST_CASE(#x) { \
|
||||
REQUIRE(x ## _txt == mstch::render(x ## _mustache, x ## _data)); \
|
||||
}
|
||||
#define MSTCH_TEST(x) \
|
||||
TEST_CASE(#x) { REQUIRE(x##_txt == mstch::render(x##_mustache, x##_data)); }
|
||||
|
||||
#define SPECS_TEST(x) TEST_CASE("specs_" #x) { \
|
||||
using boost::get; \
|
||||
auto data = parse_with_rapidjson(x ## _json); \
|
||||
for (auto& test_item: get<mstch::array>(get<mstch::map>(data)["tests"])) {\
|
||||
auto test = get<mstch::map>(test_item); \
|
||||
std::map<std::string,std::string> partials; \
|
||||
if (test.count("partials")) \
|
||||
for (auto& partial_item: get<mstch::map>(test["partials"])) \
|
||||
partials.insert(std::make_pair(partial_item.first, get<std::string>(partial_item.second))); \
|
||||
mstch::map context; \
|
||||
for (auto& data_item: get<mstch::map>(test["data"])) \
|
||||
if (data_item.first == "lambda") \
|
||||
context.insert(std::make_pair(data_item.first, specs_lambdas[get<std::string>(test["name"])])); \
|
||||
else \
|
||||
context.insert(data_item); \
|
||||
SECTION(get<std::string>(test["name"])) \
|
||||
REQUIRE(mstch::render( \
|
||||
get<std::string>(test["template"]), \
|
||||
context, partials) == \
|
||||
get<std::string>(test["expected"])); \
|
||||
} \
|
||||
}
|
||||
#define SPECS_TEST(x) \
|
||||
TEST_CASE("specs_" #x) { \
|
||||
auto data = parse_with_rapidjson(x##_json); \
|
||||
for (auto& test_item : std::get<mstch::array_wrapper>( \
|
||||
std::get<mstch::map_wrapper>(data).values["tests"]) \
|
||||
.values) { \
|
||||
auto test = std::get<mstch::map_wrapper>(test_item).values; \
|
||||
std::map<std::string, std::string> partials; \
|
||||
if (test.count("partials")) \
|
||||
for (auto& partial_item : \
|
||||
std::get<mstch::map_wrapper>(test["partials"]).values) \
|
||||
partials.insert( \
|
||||
std::make_pair(partial_item.first, \
|
||||
std::get<std::string>(partial_item.second))); \
|
||||
mstch::map context; \
|
||||
for (auto& data_item : std::get<mstch::map_wrapper>(test["data"]).values) \
|
||||
if (data_item.first == "lambda") \
|
||||
context.insert(std::make_pair( \
|
||||
data_item.first, \
|
||||
specs_lambdas[std::get<std::string>(test["name"])])); \
|
||||
else \
|
||||
context.insert(data_item); \
|
||||
SECTION(std::get<std::string>(test["name"])) \
|
||||
REQUIRE(mstch::render(std::get<std::string>(test["template"]), \
|
||||
mstch::map_wrapper{context}, \
|
||||
partials) == std::get<std::string>(test["expected"])); \
|
||||
} \
|
||||
}
|
||||
|
||||
MSTCH_TEST(ampersand_escape)
|
||||
MSTCH_TEST(apostrophe)
|
||||
|
Loading…
x
Reference in New Issue
Block a user