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 ON)
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE 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)
|
set(mstch_VERSION 1.0.1)
|
||||||
|
|
||||||
if(NOT MSVC)
|
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()
|
endif()
|
||||||
|
|
||||||
add_subdirectory(src)
|
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
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
#include <memory>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <map>
|
||||||
#include <boost/variant.hpp>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <variant>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace mstch {
|
namespace mstch {
|
||||||
|
|
||||||
struct config {
|
struct config {
|
||||||
static std::function<std::string(const std::string&)> escape;
|
static std::function<std::string(const std::string&)> escape;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template<class N>
|
template<class N>
|
||||||
class object_t {
|
class object_t {
|
||||||
public:
|
public:
|
||||||
const N& at(const std::string& name) const {
|
const N& at(const std::string& name) const {
|
||||||
cache[name] = (methods.at(name))();
|
cache[name] = (methods.at(name))();
|
||||||
return cache[name];
|
return cache[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has(const std::string name) const {
|
bool has(const std::string name) const { return methods.count(name) != 0; }
|
||||||
return methods.count(name) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
template<class S>
|
template<class S>
|
||||||
void register_methods(S* s, std::map<std::string,N(S::*)()> methods) {
|
void register_methods(S* s, std::map<std::string, N (S::*)()> methods) {
|
||||||
for(auto& item: methods)
|
for (auto& item : methods)
|
||||||
this->methods.insert({item.first, std::bind(item.second, s)});
|
this->methods.insert({item.first, std::bind(item.second, s)});
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<std::string, std::function<N()>> methods;
|
std::map<std::string, std::function<N()>> methods;
|
||||||
mutable std::map<std::string, N> cache;
|
mutable std::map<std::string, N> cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T, class N>
|
template<class T, class N>
|
||||||
class is_fun {
|
class is_fun {
|
||||||
private:
|
private:
|
||||||
using not_fun = char;
|
using not_fun = char;
|
||||||
using fun_without_args = char[2];
|
using fun_without_args = char[2];
|
||||||
using fun_with_args = char[3];
|
using fun_with_args = char[3];
|
||||||
template <typename U, U> struct really_has;
|
template<typename U, U>
|
||||||
template <typename C> static fun_without_args& test(
|
struct really_has;
|
||||||
really_has<N(C::*)() const, &C::operator()>*);
|
template<typename C>
|
||||||
template <typename C> static fun_with_args& test(
|
static fun_without_args& test(really_has<N (C::*)() const, &C::operator()>*);
|
||||||
really_has<N(C::*)(const std::string&) const,
|
template<typename C>
|
||||||
&C::operator()>*);
|
static fun_with_args& test(really_has<N (C::*)(const std::string&) const, &C::operator()>*);
|
||||||
template <typename> static not_fun& test(...);
|
template<typename>
|
||||||
|
static not_fun& test(...);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static bool const no_args = sizeof(test<T>(0)) == sizeof(fun_without_args);
|
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);
|
static bool const has_args = sizeof(test<T>(0)) == sizeof(fun_with_args);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class N>
|
template<class N>
|
||||||
@ -64,50 +62,68 @@ using node_renderer = std::function<std::string(const N& n)>;
|
|||||||
|
|
||||||
template<class N>
|
template<class N>
|
||||||
class lambda_t {
|
class lambda_t {
|
||||||
public:
|
public:
|
||||||
template<class F>
|
template<class F>
|
||||||
lambda_t(F f, typename std::enable_if<is_fun<F, N>::no_args>::type* = 0):
|
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&) {
|
: fun([f](node_renderer<N> renderer, const std::string&) { return renderer(f()); })
|
||||||
return renderer(f());
|
{}
|
||||||
})
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class F>
|
template<class F>
|
||||||
lambda_t(F f, typename std::enable_if<is_fun<F, N>::has_args>::type* = 0):
|
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) {
|
: fun([f](node_renderer<N> renderer, const std::string& text) {
|
||||||
return renderer(f(text));
|
return renderer(f(text));
|
||||||
})
|
})
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
std::string operator()(node_renderer<N> renderer,
|
std::string operator()(node_renderer<N> renderer, const std::string& text = "") const {
|
||||||
const std::string& text = "") const
|
return fun(renderer, text);
|
||||||
{
|
}
|
||||||
return fun(renderer, text);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::function<std::string(node_renderer<N> renderer, const std::string&)> fun;
|
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 object = internal::object_t<node>;
|
||||||
using lambda = internal::lambda_t<node>;
|
using lambda = internal::lambda_t<node>;
|
||||||
using map = std::map<const std::string, node>;
|
using map = std::map<const std::string, node>;
|
||||||
using array = std::vector<node>;
|
using array = std::vector<node>;
|
||||||
|
|
||||||
std::string render(
|
struct array_wrapper {
|
||||||
const std::string& tmplt,
|
array values;
|
||||||
const node& root,
|
};
|
||||||
const std::map<std::string,std::string>& partials =
|
|
||||||
std::map<std::string,std::string>());
|
|
||||||
|
|
||||||
}
|
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
|
set(mstch_INCLUDE_DIR
|
||||||
${PROJECT_SOURCE_DIR}/include CACHE STRING "mstch include directory")
|
${PROJECT_SOURCE_DIR}/include CACHE STRING "mstch include directory")
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${mstch_INCLUDE_DIR}
|
${mstch_INCLUDE_DIR})
|
||||||
${Boost_INCLUDE_DIR})
|
|
||||||
|
|
||||||
set(SRC
|
set(SRC
|
||||||
state/in_section.cpp
|
state/in_section.cpp
|
||||||
|
@ -7,14 +7,13 @@ using namespace mstch;
|
|||||||
|
|
||||||
std::function<std::string(const std::string&)> mstch::config::escape;
|
std::function<std::string(const std::string&)> mstch::config::escape;
|
||||||
|
|
||||||
std::string mstch::render(
|
std::string mstch::render(const std::string& tmplt,
|
||||||
const std::string& tmplt,
|
const node& root,
|
||||||
const node& root,
|
const std::map<std::string, std::string>& partials)
|
||||||
const std::map<std::string,std::string>& partials)
|
|
||||||
{
|
{
|
||||||
std::map<std::string, template_type> partial_templates;
|
std::map<std::string, template_type> partial_templates;
|
||||||
for (auto& partial: partials)
|
for (auto& partial : partials)
|
||||||
partial_templates.insert({partial.first, {partial.second}});
|
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;
|
const mstch::node render_context::null_node;
|
||||||
|
|
||||||
render_context::push::push(render_context& context, const mstch::node& node):
|
render_context::push::push(render_context& context, const mstch::node& node)
|
||||||
m_context(context)
|
: m_context(context)
|
||||||
{
|
{
|
||||||
context.m_nodes.emplace_front(node);
|
context.m_nodes.emplace_front(node);
|
||||||
context.m_node_ptrs.emplace_front(&node);
|
context.m_node_ptrs.emplace_front(&node);
|
||||||
context.m_state.push(std::unique_ptr<render_state>(new outside_section));
|
context.m_state.push(std::unique_ptr<render_state>(new outside_section));
|
||||||
}
|
}
|
||||||
|
|
||||||
render_context::push::~push() {
|
render_context::push::~push() {
|
||||||
m_context.m_nodes.pop_front();
|
m_context.m_nodes.pop_front();
|
||||||
m_context.m_node_ptrs.pop_front();
|
m_context.m_node_ptrs.pop_front();
|
||||||
m_context.m_state.pop();
|
m_context.m_state.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string render_context::push::render(const template_type& templt) {
|
std::string render_context::push::render(const template_type& templt) {
|
||||||
return m_context.render(templt);
|
return m_context.render(templt);
|
||||||
}
|
}
|
||||||
|
|
||||||
render_context::render_context(
|
render_context::render_context(const mstch::node& node,
|
||||||
const mstch::node& node,
|
const std::map<std::string, template_type>& partials)
|
||||||
const std::map<std::string, template_type>& partials):
|
: m_partials(partials), m_nodes(1, node), m_node_ptrs(1, &node)
|
||||||
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 mstch::node& render_context::find_node(const std::string& token,
|
||||||
const std::string& token,
|
std::list<node const*> current_nodes)
|
||||||
std::list<node const*> current_nodes)
|
|
||||||
{
|
{
|
||||||
if (token != "." && token.find('.') != std::string::npos)
|
if (token != "." && token.find('.') != std::string::npos)
|
||||||
return find_node(token.substr(token.rfind('.') + 1),
|
return find_node(token.substr(token.rfind('.') + 1),
|
||||||
{&find_node(token.substr(0, token.rfind('.')), current_nodes)});
|
{&find_node(token.substr(0, token.rfind('.')), current_nodes)});
|
||||||
else
|
else
|
||||||
for (auto& node: current_nodes)
|
for (auto& node : current_nodes)
|
||||||
if (visit(has_token(token), *node))
|
if (visit(has_token(token), *node))
|
||||||
return visit(get_token(token, *node), *node);
|
return visit(get_token(token, *node), *node);
|
||||||
return null_node;
|
return null_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
const mstch::node& render_context::get_node(const std::string& token) {
|
const mstch::node& render_context::get_node(const std::string& token) {
|
||||||
return find_node(token, m_node_ptrs);
|
return find_node(token, m_node_ptrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string render_context::render(
|
std::string render_context::render(const template_type& templt, const std::string& prefix) {
|
||||||
const template_type& templt, const std::string& prefix)
|
std::string output;
|
||||||
{
|
bool prev_eol = true;
|
||||||
std::string output;
|
for (auto& token : templt) {
|
||||||
bool prev_eol = true;
|
if (prev_eol && prefix.length() != 0)
|
||||||
for (auto& token: templt) {
|
output += m_state.top()->render(*this, {prefix});
|
||||||
if (prev_eol && prefix.length() != 0)
|
output += m_state.top()->render(*this, token);
|
||||||
output += m_state.top()->render(*this, {prefix});
|
prev_eol = token.eol();
|
||||||
output += m_state.top()->render(*this, token);
|
}
|
||||||
prev_eol = token.eol();
|
return output;
|
||||||
}
|
|
||||||
return output;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string render_context::render_partial(
|
std::string render_context::render_partial(const std::string& partial_name,
|
||||||
const std::string& partial_name, const std::string& prefix)
|
const std::string& prefix)
|
||||||
{
|
{
|
||||||
return m_partials.count(partial_name) ?
|
return m_partials.count(partial_name) ? render(m_partials.at(partial_name), prefix) : "";
|
||||||
render(m_partials.at(partial_name), prefix) : "";
|
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
#include <deque>
|
#include <deque>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "mstch/mstch.hpp"
|
#include "mstch/mstch.hpp"
|
||||||
#include "state/render_state.hpp"
|
#include "state/render_state.hpp"
|
||||||
@ -13,39 +13,35 @@
|
|||||||
namespace mstch {
|
namespace mstch {
|
||||||
|
|
||||||
class render_context {
|
class render_context {
|
||||||
public:
|
public:
|
||||||
class push {
|
class push {
|
||||||
public:
|
public:
|
||||||
push(render_context& context, const mstch::node& node = {});
|
push(render_context& context, const mstch::node& node = {});
|
||||||
~push();
|
~push();
|
||||||
std::string render(const template_type& templt);
|
std::string render(const template_type& templt);
|
||||||
private:
|
|
||||||
render_context& m_context;
|
|
||||||
};
|
|
||||||
|
|
||||||
render_context(
|
private:
|
||||||
const mstch::node& node,
|
render_context& m_context;
|
||||||
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(const mstch::node& node,
|
||||||
static const mstch::node null_node;
|
const std::map<std::string, template_type>& partials);
|
||||||
const mstch::node& find_node(
|
const mstch::node& get_node(const std::string& token);
|
||||||
const std::string& token,
|
std::string render(const template_type& templt, const std::string& prefix = "");
|
||||||
std::list<node const*> current_nodes);
|
std::string render_partial(const std::string& partial_name, const std::string& prefix);
|
||||||
std::map<std::string, template_type> m_partials;
|
template<class T, class... Args>
|
||||||
std::deque<mstch::node> m_nodes;
|
void set_state(Args&&... args) {
|
||||||
std::list<const mstch::node*> m_node_ptrs;
|
m_state.top() = std::unique_ptr<render_state>(new T(std::forward<Args>(args)...));
|
||||||
std::stack<std::unique_ptr<render_state>> m_state;
|
}
|
||||||
|
|
||||||
|
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;
|
using namespace mstch;
|
||||||
|
|
||||||
in_section::in_section(type type, const token& start_token):
|
in_section::in_section(type type, const token& start_token)
|
||||||
m_type(type), m_start_token(start_token), m_skipped_openings(0)
|
: m_type(type), m_start_token(start_token), m_skipped_openings(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string in_section::render(render_context& ctx, const token& token) {
|
std::string in_section::render(render_context& ctx, const token& token) {
|
||||||
if (token.token_type() == token::type::section_close)
|
if (token.token_type() == token::type::section_close)
|
||||||
if (token.name() == m_start_token.name() && m_skipped_openings == 0) {
|
if (token.name() == m_start_token.name() && m_skipped_openings == 0) {
|
||||||
auto& node = ctx.get_node(m_start_token.name());
|
auto& node = ctx.get_node(m_start_token.name());
|
||||||
std::string out;
|
std::string out;
|
||||||
|
|
||||||
if (m_type == type::normal && !visit(is_node_empty(), node))
|
if (m_type == type::normal && !visit(is_node_empty(), node))
|
||||||
out = visit(render_section(ctx, m_section, m_start_token.delims()), node);
|
out = visit(render_section(ctx, m_section, m_start_token.delims()), node);
|
||||||
else if (m_type == type::inverted && visit(is_node_empty(), node))
|
else if (m_type == type::inverted && visit(is_node_empty(), node))
|
||||||
out = render_context::push(ctx).render(m_section);
|
out = render_context::push(ctx).render(m_section);
|
||||||
|
|
||||||
ctx.set_state<outside_section>();
|
ctx.set_state<outside_section>();
|
||||||
return out;
|
return out;
|
||||||
} else
|
} else
|
||||||
m_skipped_openings--;
|
m_skipped_openings--;
|
||||||
else if (token.token_type() == token::type::inverted_section_open ||
|
else if (token.token_type() == token::type::inverted_section_open ||
|
||||||
token.token_type() == token::type::section_open)
|
token.token_type() == token::type::section_open)
|
||||||
m_skipped_openings++;
|
m_skipped_openings++;
|
||||||
|
|
||||||
m_section << token;
|
m_section << token;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -8,17 +8,17 @@
|
|||||||
|
|
||||||
namespace mstch {
|
namespace mstch {
|
||||||
|
|
||||||
class in_section: public render_state {
|
class in_section : public render_state {
|
||||||
public:
|
public:
|
||||||
enum class type { inverted, normal };
|
enum class type { inverted, normal };
|
||||||
in_section(type type, const token& start_token);
|
in_section(type type, const token& start_token);
|
||||||
std::string render(render_context& context, const token& token) override;
|
std::string render(render_context& context, const token& token) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const type m_type;
|
const type m_type;
|
||||||
const token& m_start_token;
|
const token& m_start_token;
|
||||||
template_type m_section;
|
template_type m_section;
|
||||||
int m_skipped_openings;
|
int m_skipped_openings;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace mstch
|
||||||
|
@ -1,32 +1,30 @@
|
|||||||
#include "outside_section.hpp"
|
#include "outside_section.hpp"
|
||||||
|
|
||||||
#include "visitor/render_node.hpp"
|
|
||||||
#include "in_section.hpp"
|
#include "in_section.hpp"
|
||||||
#include "render_context.hpp"
|
#include "render_context.hpp"
|
||||||
|
#include "visitor/render_node.hpp"
|
||||||
|
|
||||||
using namespace mstch;
|
using namespace mstch;
|
||||||
|
|
||||||
std::string outside_section::render(
|
std::string outside_section::render(render_context& ctx, const token& token) {
|
||||||
render_context& ctx, const token& token)
|
using flag = render_node::flag;
|
||||||
{
|
switch (token.token_type()) {
|
||||||
using flag = render_node::flag;
|
|
||||||
switch (token.token_type()) {
|
|
||||||
case token::type::section_open:
|
case token::type::section_open:
|
||||||
ctx.set_state<in_section>(in_section::type::normal, token);
|
ctx.set_state<in_section>(in_section::type::normal, token);
|
||||||
break;
|
break;
|
||||||
case token::type::inverted_section_open:
|
case token::type::inverted_section_open:
|
||||||
ctx.set_state<in_section>(in_section::type::inverted, token);
|
ctx.set_state<in_section>(in_section::type::inverted, token);
|
||||||
break;
|
break;
|
||||||
case token::type::variable:
|
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:
|
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:
|
case token::type::text:
|
||||||
return token.raw();
|
return token.raw();
|
||||||
case token::type::partial:
|
case token::type::partial:
|
||||||
return ctx.render_partial(token.name(), token.partial_prefix());
|
return ctx.render_partial(token.name(), token.partial_prefix());
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
namespace mstch {
|
namespace mstch {
|
||||||
|
|
||||||
class outside_section: public render_state {
|
class outside_section : public render_state {
|
||||||
public:
|
public:
|
||||||
std::string render(render_context& context, const token& token) override;
|
std::string render(render_context& context, const token& token) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace mstch
|
||||||
|
@ -9,9 +9,9 @@ namespace mstch {
|
|||||||
class render_context;
|
class render_context;
|
||||||
|
|
||||||
class render_state {
|
class render_state {
|
||||||
public:
|
public:
|
||||||
virtual ~render_state() {}
|
virtual ~render_state() {}
|
||||||
virtual std::string render(render_context& context, const token& token) = 0;
|
virtual std::string render(render_context& context, const token& token) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace mstch
|
||||||
|
@ -2,103 +2,98 @@
|
|||||||
|
|
||||||
using namespace mstch;
|
using namespace mstch;
|
||||||
|
|
||||||
template_type::template_type(const std::string& str, const delim_type& delims):
|
template_type::template_type(const std::string& str, const delim_type& delims)
|
||||||
m_open(delims.first), m_close(delims.second)
|
: m_open(delims.first), m_close(delims.second)
|
||||||
{
|
{
|
||||||
tokenize(str);
|
tokenize(str);
|
||||||
strip_whitespace();
|
strip_whitespace();
|
||||||
}
|
}
|
||||||
|
|
||||||
template_type::template_type(const std::string& str):
|
template_type::template_type(const std::string& str) : m_open("{{"), m_close("}}") {
|
||||||
m_open("{{"), m_close("}}")
|
tokenize(str);
|
||||||
{
|
strip_whitespace();
|
||||||
tokenize(str);
|
|
||||||
strip_whitespace();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void template_type::process_text(citer begin, citer end) {
|
void template_type::process_text(citer begin, citer end) {
|
||||||
if (begin == end)
|
if (begin == end)
|
||||||
return;
|
return;
|
||||||
auto start = begin;
|
auto start = begin;
|
||||||
for (auto it = begin; it != end; ++it)
|
for (auto it = begin; it != end; ++it)
|
||||||
if (*it == '\n' || it == end - 1) {
|
if (*it == '\n' || it == end - 1) {
|
||||||
m_tokens.push_back({{start, it + 1}});
|
m_tokens.push_back({{start, it + 1}});
|
||||||
start = it + 1;
|
start = it + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void template_type::tokenize(const std::string& tmp) {
|
void template_type::tokenize(const std::string& tmp) {
|
||||||
citer beg = tmp.begin();
|
citer beg = tmp.begin();
|
||||||
auto npos = std::string::npos;
|
auto npos = std::string::npos;
|
||||||
|
|
||||||
for (std::size_t cur_pos = 0; cur_pos < tmp.size();) {
|
for (std::size_t cur_pos = 0; cur_pos < tmp.size();) {
|
||||||
auto open_pos = tmp.find(m_open, cur_pos);
|
auto open_pos = tmp.find(m_open, cur_pos);
|
||||||
auto close_pos = tmp.find(
|
auto close_pos = tmp.find(m_close, open_pos == npos ? open_pos : open_pos + 1);
|
||||||
m_close, open_pos == npos ? open_pos : open_pos + 1);
|
|
||||||
|
|
||||||
if (close_pos != npos && open_pos != npos) {
|
if (close_pos != npos && open_pos != npos) {
|
||||||
if (*(beg + open_pos + m_open.size()) == '{' &&
|
if (*(beg + open_pos + m_open.size()) == '{' &&
|
||||||
*(beg + close_pos + m_close.size()) == '}')
|
*(beg + close_pos + m_close.size()) == '}')
|
||||||
++close_pos;
|
++close_pos;
|
||||||
|
|
||||||
process_text(beg + cur_pos, beg + open_pos);
|
process_text(beg + cur_pos, beg + open_pos);
|
||||||
cur_pos = close_pos + m_close.size();
|
cur_pos = close_pos + m_close.size();
|
||||||
m_tokens.push_back({{beg + open_pos, beg + close_pos + m_close.size()},
|
m_tokens.push_back({{beg + open_pos, beg + close_pos + m_close.size()},
|
||||||
m_open.size(), m_close.size()});
|
m_open.size(),
|
||||||
|
m_close.size()});
|
||||||
|
|
||||||
if (cur_pos == tmp.size()) {
|
if (cur_pos == tmp.size()) {
|
||||||
m_tokens.push_back({{""}});
|
m_tokens.push_back({{""}});
|
||||||
m_tokens.back().eol(true);
|
m_tokens.back().eol(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*(beg + open_pos + m_open.size()) == '=' &&
|
if (*(beg + open_pos + m_open.size()) == '=' && *(beg + close_pos - 1) == '=') {
|
||||||
*(beg + close_pos - 1) == '=')
|
auto tok_beg = beg + open_pos + m_open.size() + 1;
|
||||||
{
|
auto tok_end = beg + close_pos - 1;
|
||||||
auto tok_beg = beg + open_pos + m_open.size() + 1;
|
auto front_skip = first_not_ws(tok_beg, tok_end);
|
||||||
auto tok_end = beg + close_pos - 1;
|
auto back_skip = first_not_ws(reverse(tok_end), reverse(tok_beg));
|
||||||
auto front_skip = first_not_ws(tok_beg, tok_end);
|
m_open = {front_skip, beg + tmp.find(' ', front_skip - beg)};
|
||||||
auto back_skip = first_not_ws(reverse(tok_end), reverse(tok_beg));
|
m_close = {beg + tmp.rfind(' ', back_skip - beg) + 1, back_skip + 1};
|
||||||
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());
|
||||||
} else {
|
cur_pos = close_pos;
|
||||||
process_text(beg + cur_pos, tmp.end());
|
}
|
||||||
cur_pos = close_pos;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void template_type::strip_whitespace() {
|
void template_type::strip_whitespace() {
|
||||||
auto line_begin = m_tokens.begin();
|
auto line_begin = m_tokens.begin();
|
||||||
bool has_tag = false, non_space = false;
|
bool has_tag = false, non_space = false;
|
||||||
|
|
||||||
for (auto it = m_tokens.begin(); it != m_tokens.end(); ++it) {
|
for (auto it = m_tokens.begin(); it != m_tokens.end(); ++it) {
|
||||||
auto type = (*it).token_type();
|
auto type = (*it).token_type();
|
||||||
if (type != token::type::text && type != token::type::variable &&
|
if (type != token::type::text && type != token::type::variable &&
|
||||||
type != token::type::unescaped_variable)
|
type != token::type::unescaped_variable)
|
||||||
has_tag = true;
|
has_tag = true;
|
||||||
else if (!(*it).ws_only())
|
else if (!(*it).ws_only())
|
||||||
non_space = true;
|
non_space = true;
|
||||||
|
|
||||||
if ((*it).eol()) {
|
if ((*it).eol()) {
|
||||||
if (has_tag && !non_space) {
|
if (has_tag && !non_space) {
|
||||||
store_prefixes(line_begin);
|
store_prefixes(line_begin);
|
||||||
|
|
||||||
auto c = line_begin;
|
auto c = line_begin;
|
||||||
for (bool end = false; !end; (*c).ws_only() ? c = m_tokens.erase(c) : ++c)
|
for (bool end = false; !end; (*c).ws_only() ? c = m_tokens.erase(c) : ++c)
|
||||||
if ((end = (*c).eol()))
|
if ((end = (*c).eol()))
|
||||||
it = c - 1;
|
it = c - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
non_space = has_tag = false;
|
non_space = has_tag = false;
|
||||||
line_begin = it + 1;
|
line_begin = it + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void template_type::store_prefixes(std::vector<token>::iterator beg) {
|
void template_type::store_prefixes(std::vector<token>::iterator beg) {
|
||||||
for (auto cur = beg; !(*cur).eol(); ++cur)
|
for (auto cur = beg; !(*cur).eol(); ++cur)
|
||||||
if ((*cur).token_type() == token::type::partial &&
|
if ((*cur).token_type() == token::type::partial && cur != beg && (*(cur - 1)).ws_only())
|
||||||
cur != beg && (*(cur - 1)).ws_only())
|
(*cur).partial_prefix((*(cur - 1)).raw());
|
||||||
(*cur).partial_prefix((*(cur - 1)).raw());
|
|
||||||
}
|
}
|
||||||
|
@ -9,22 +9,22 @@
|
|||||||
namespace mstch {
|
namespace mstch {
|
||||||
|
|
||||||
class template_type {
|
class template_type {
|
||||||
public:
|
public:
|
||||||
template_type() = default;
|
template_type() = default;
|
||||||
template_type(const std::string& str);
|
template_type(const std::string& str);
|
||||||
template_type(const std::string& str, const delim_type& delims);
|
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 begin() const { return m_tokens.begin(); }
|
||||||
std::vector<token>::const_iterator end() const { return m_tokens.end(); }
|
std::vector<token>::const_iterator end() const { return m_tokens.end(); }
|
||||||
void operator<<(const token& token) { m_tokens.push_back(token); }
|
void operator<<(const token& token) { m_tokens.push_back(token); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<token> m_tokens;
|
std::vector<token> m_tokens;
|
||||||
std::string m_open;
|
std::string m_open;
|
||||||
std::string m_close;
|
std::string m_close;
|
||||||
void strip_whitespace();
|
void strip_whitespace();
|
||||||
void process_text(citer beg, citer end);
|
void process_text(citer beg, citer end);
|
||||||
void tokenize(const std::string& tmp);
|
void tokenize(const std::string& tmp);
|
||||||
void store_prefixes(std::vector<token>::iterator beg);
|
void store_prefixes(std::vector<token>::iterator beg);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace mstch
|
||||||
|
@ -4,39 +4,45 @@
|
|||||||
using namespace mstch;
|
using namespace mstch;
|
||||||
|
|
||||||
token::type token::token_info(char c) {
|
token::type token::token_info(char c) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '>': return type::partial;
|
case '>':
|
||||||
case '^': return type::inverted_section_open;
|
return type::partial;
|
||||||
case '/': return type::section_close;
|
case '^':
|
||||||
case '&': return type::unescaped_variable;
|
return type::inverted_section_open;
|
||||||
case '#': return type::section_open;
|
case '/':
|
||||||
case '!': return type::comment;
|
return type::section_close;
|
||||||
default: return type::variable;
|
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):
|
token::token(const std::string& str, std::size_t left, std::size_t right)
|
||||||
m_raw(str), m_eol(false), m_ws_only(false)
|
: m_raw(str), m_eol(false), m_ws_only(false)
|
||||||
{
|
{
|
||||||
if (left != 0 && right != 0) {
|
if (left != 0 && right != 0) {
|
||||||
if (str[left] == '=' && str[str.size() - right - 1] == '=') {
|
if (str[left] == '=' && str[str.size() - right - 1] == '=') {
|
||||||
m_type = type::delimiter_change;
|
m_type = type::delimiter_change;
|
||||||
} else if (str[left] == '{' && str[str.size() - right - 1] == '}') {
|
} else if (str[left] == '{' && str[str.size() - right - 1] == '}') {
|
||||||
m_type = type::unescaped_variable;
|
m_type = type::unescaped_variable;
|
||||||
m_name = {first_not_ws(str.begin() + left + 1, str.end() - right),
|
m_name = {first_not_ws(str.begin() + left + 1, str.end() - right),
|
||||||
first_not_ws(str.rbegin() + 1 + right, str.rend() - left) + 1};
|
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 {
|
} else {
|
||||||
auto c = first_not_ws(str.begin() + left, str.end() - right);
|
m_type = type::text;
|
||||||
m_type = token_info(*c);
|
m_eol = (str.size() > 0 && str[str.size() - 1] == '\n');
|
||||||
if (m_type != type::variable)
|
m_ws_only = (str.find_first_not_of(" \r\n\t") == std::string::npos);
|
||||||
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 {
|
|
||||||
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>;
|
using delim_type = std::pair<std::string, std::string>;
|
||||||
|
|
||||||
class token {
|
class token {
|
||||||
public:
|
public:
|
||||||
enum class type {
|
enum class type {
|
||||||
text, variable, section_open, section_close, inverted_section_open,
|
text,
|
||||||
unescaped_variable, comment, partial, delimiter_change
|
variable,
|
||||||
};
|
section_open,
|
||||||
token(const std::string& str, std::size_t left = 0, std::size_t right = 0);
|
section_close,
|
||||||
type token_type() const { return m_type; };
|
inverted_section_open,
|
||||||
const std::string& raw() const { return m_raw; };
|
unescaped_variable,
|
||||||
const std::string& name() const { return m_name; };
|
comment,
|
||||||
const std::string& partial_prefix() const { return m_partial_prefix; };
|
partial,
|
||||||
const delim_type& delims() const { return m_delims; };
|
delimiter_change
|
||||||
void partial_prefix(const std::string& p_partial_prefix) {
|
};
|
||||||
m_partial_prefix = p_partial_prefix;
|
token(const std::string& str, std::size_t left = 0, std::size_t right = 0);
|
||||||
};
|
type token_type() const { return m_type; };
|
||||||
bool eol() const { return m_eol; }
|
const std::string& raw() const { return m_raw; };
|
||||||
void eol(bool eol) { m_eol = eol; }
|
const std::string& name() const { return m_name; };
|
||||||
bool ws_only() const { return m_ws_only; }
|
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:
|
private:
|
||||||
type m_type;
|
type m_type;
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
std::string m_raw;
|
std::string m_raw;
|
||||||
std::string m_partial_prefix;
|
std::string m_partial_prefix;
|
||||||
delim_type m_delims;
|
delim_type m_delims;
|
||||||
bool m_eol;
|
bool m_eol;
|
||||||
bool m_ws_only;
|
bool m_ws_only;
|
||||||
type token_info(char c);
|
type token_info(char c);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace mstch
|
||||||
|
@ -2,43 +2,58 @@
|
|||||||
#include "mstch/mstch.hpp"
|
#include "mstch/mstch.hpp"
|
||||||
|
|
||||||
mstch::citer mstch::first_not_ws(mstch::citer begin, mstch::citer end) {
|
mstch::citer mstch::first_not_ws(mstch::citer begin, mstch::citer end) {
|
||||||
for (auto it = begin; it != end; ++it)
|
for (auto it = begin; it != end; ++it)
|
||||||
if (*it != ' ') return it;
|
if (*it != ' ')
|
||||||
return end;
|
return it;
|
||||||
|
return end;
|
||||||
}
|
}
|
||||||
|
|
||||||
mstch::citer mstch::first_not_ws(mstch::criter begin, mstch::criter end) {
|
mstch::citer mstch::first_not_ws(mstch::criter begin, mstch::criter end) {
|
||||||
for (auto rit = begin; rit != end; ++rit)
|
for (auto rit = begin; rit != end; ++rit)
|
||||||
if (*rit != ' ') return --(rit.base());
|
if (*rit != ' ')
|
||||||
return --(end.base());
|
return --(rit.base());
|
||||||
|
return --(end.base());
|
||||||
}
|
}
|
||||||
|
|
||||||
mstch::criter mstch::reverse(mstch::citer it) {
|
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) {
|
std::string mstch::html_escape(const std::string& str) {
|
||||||
if (mstch::config::escape)
|
if (mstch::config::escape)
|
||||||
return mstch::config::escape(str);
|
return mstch::config::escape(str);
|
||||||
|
|
||||||
std::string out;
|
|
||||||
citer start = str.begin();
|
|
||||||
|
|
||||||
auto add_escape = [&out, &start](const std::string& escaped, citer& it) {
|
std::string out;
|
||||||
out += std::string{start, it} + escaped;
|
citer start = str.begin();
|
||||||
start = it + 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
for (auto it = str.begin(); it != str.end(); ++it)
|
auto add_escape = [&out, &start](const std::string& escaped, citer& it) {
|
||||||
switch (*it) {
|
out += std::string{start, it} + escaped;
|
||||||
case '&': add_escape("&", it); break;
|
start = it + 1;
|
||||||
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()};
|
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()};
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <boost/variant/apply_visitor.hpp>
|
#include <variant>
|
||||||
|
|
||||||
namespace mstch {
|
namespace mstch {
|
||||||
|
|
||||||
using citer = std::string::const_iterator;
|
using citer = std::string::const_iterator;
|
||||||
using criter = std::string::const_reverse_iterator;
|
using criter = std::string::const_reverse_iterator;
|
||||||
|
|
||||||
citer first_not_ws(citer begin, citer end);
|
citer first_not_ws(citer begin, citer end);
|
||||||
@ -14,10 +14,8 @@ std::string html_escape(const std::string& str);
|
|||||||
criter reverse(citer it);
|
criter reverse(citer it);
|
||||||
|
|
||||||
template<class... Args>
|
template<class... Args>
|
||||||
auto visit(Args&&... args) -> decltype(boost::apply_visitor(
|
auto visit(Args&&... args) -> decltype(std::visit(std::forward<Args>(args)...)) {
|
||||||
std::forward<Args>(args)...))
|
return std::visit(std::forward<Args>(args)...);
|
||||||
{
|
|
||||||
return boost::apply_visitor(std::forward<Args>(args)...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace mstch
|
||||||
|
@ -1,35 +1,32 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <boost/variant/static_visitor.hpp>
|
|
||||||
|
|
||||||
#include "mstch/mstch.hpp"
|
|
||||||
#include "has_token.hpp"
|
#include "has_token.hpp"
|
||||||
|
#include "mstch/mstch.hpp"
|
||||||
|
|
||||||
namespace mstch {
|
namespace mstch {
|
||||||
|
|
||||||
class get_token: public boost::static_visitor<const mstch::node&> {
|
class get_token {
|
||||||
public:
|
public:
|
||||||
get_token(const std::string& token, const mstch::node& node):
|
get_token(const std::string& token, const mstch::node& node)
|
||||||
m_token(token), m_node(node)
|
: m_token(token), m_node(node)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
const mstch::node& operator()(const T&) const {
|
const mstch::node& operator()(const T&) const {
|
||||||
return m_node;
|
return m_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
const mstch::node& operator()(const map& map) const {
|
const mstch::node& operator()(const map_wrapper& map) const {
|
||||||
return map.at(m_token);
|
return map.values.at(m_token);
|
||||||
}
|
}
|
||||||
|
|
||||||
const mstch::node& operator()(const std::shared_ptr<object>& object) const {
|
const mstch::node& operator()(const object_wrapper& object) const {
|
||||||
return object->at(m_token);
|
return object.values->at(m_token);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::string& m_token;
|
const std::string& m_token;
|
||||||
const mstch::node& m_node;
|
const mstch::node& m_node;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace mstch
|
||||||
|
@ -1,31 +1,24 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <boost/variant/static_visitor.hpp>
|
|
||||||
|
|
||||||
#include "mstch/mstch.hpp"
|
#include "mstch/mstch.hpp"
|
||||||
|
|
||||||
namespace mstch {
|
namespace mstch {
|
||||||
|
|
||||||
class has_token: public boost::static_visitor<bool> {
|
class has_token {
|
||||||
public:
|
public:
|
||||||
has_token(const std::string& token): m_token(token) {
|
has_token(const std::string& token) : m_token(token) {}
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
bool operator()(const T&) const {
|
bool operator()(const T&) const {
|
||||||
return m_token == ".";
|
return m_token == ".";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()(const map& map) const {
|
bool operator()(const map_wrapper& map) const { return map.values.count(m_token) == 1; }
|
||||||
return map.count(m_token) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(const std::shared_ptr<object>& object) const {
|
bool operator()(const object_wrapper& object) const { return object.values->has(m_token); }
|
||||||
return object->has(m_token);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::string& m_token;
|
const std::string& m_token;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace mstch
|
||||||
|
@ -1,41 +1,27 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <boost/variant/static_visitor.hpp>
|
|
||||||
|
|
||||||
#include "mstch/mstch.hpp"
|
#include "mstch/mstch.hpp"
|
||||||
|
|
||||||
namespace mstch {
|
namespace mstch {
|
||||||
|
|
||||||
class is_node_empty: public boost::static_visitor<bool> {
|
class is_node_empty {
|
||||||
public:
|
public:
|
||||||
template<class T>
|
template<class T>
|
||||||
bool operator()(const T&) const {
|
bool operator()(const T&) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()(const std::nullptr_t&) const {
|
bool operator()(const std::nullptr_t&) const { return true; }
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(const int& value) const {
|
bool operator()(const int& value) const { return value == 0; }
|
||||||
return value == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(const double& value) const {
|
bool operator()(const double& value) const { return value == 0; }
|
||||||
return value == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(const bool& value) const {
|
bool operator()(const bool& value) const { return !value; }
|
||||||
return !value;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(const std::string& value) const {
|
bool operator()(const std::string& value) const { return value == ""; }
|
||||||
return value == "";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(const array& array) const {
|
bool operator()(const array_wrapper& array) const { return array.values.size() == 0; }
|
||||||
return array.size() == 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace mstch
|
||||||
|
@ -1,56 +1,48 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <boost/variant/static_visitor.hpp>
|
|
||||||
|
|
||||||
#include "render_context.hpp"
|
|
||||||
#include "mstch/mstch.hpp"
|
#include "mstch/mstch.hpp"
|
||||||
|
#include "render_context.hpp"
|
||||||
#include "utils.hpp"
|
#include "utils.hpp"
|
||||||
|
|
||||||
namespace mstch {
|
namespace mstch {
|
||||||
|
|
||||||
class render_node: public boost::static_visitor<std::string> {
|
class render_node {
|
||||||
public:
|
public:
|
||||||
enum class flag { none, escape_html };
|
enum class flag { none, escape_html };
|
||||||
render_node(render_context& ctx, flag p_flag = flag::none):
|
render_node(render_context& ctx, flag p_flag = flag::none) : m_ctx(ctx), m_flag(p_flag) {}
|
||||||
m_ctx(ctx), m_flag(p_flag)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
std::string operator()(const T&) const {
|
std::string operator()(const T&) const {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string operator()(const int& value) const {
|
std::string operator()(const int& value) const { return std::to_string(value); }
|
||||||
return std::to_string(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string operator()(const double& value) const {
|
std::string operator()(const double& value) const {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << value;
|
ss << value;
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string operator()(const bool& value) const {
|
std::string operator()(const bool& value) const { return value ? "true" : "false"; }
|
||||||
return value ? "true" : "false";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string operator()(const lambda& value) const {
|
std::string operator()(const lambda_wrapper& value) const {
|
||||||
template_type interpreted{value([this](const mstch::node& n) {
|
template_type interpreted{value.values(
|
||||||
return visit(render_node(m_ctx), n);
|
[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 std::string& value) const {
|
auto rendered = render_context::push(m_ctx).render(interpreted);
|
||||||
return (m_flag == flag::escape_html) ? html_escape(value) : value;
|
return (m_flag == flag::escape_html) ? html_escape(rendered) : rendered;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
std::string operator()(const std::string& value) const {
|
||||||
render_context& m_ctx;
|
return (m_flag == flag::escape_html) ? html_escape(value) : value;
|
||||||
flag m_flag;
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
render_context& m_ctx;
|
||||||
|
flag m_flag;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace mstch
|
||||||
|
@ -1,57 +1,57 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <boost/variant/static_visitor.hpp>
|
|
||||||
|
|
||||||
#include "render_context.hpp"
|
|
||||||
#include "mstch/mstch.hpp"
|
#include "mstch/mstch.hpp"
|
||||||
#include "utils.hpp"
|
#include "render_context.hpp"
|
||||||
#include "render_node.hpp"
|
#include "render_node.hpp"
|
||||||
|
#include "utils.hpp"
|
||||||
|
|
||||||
namespace mstch {
|
namespace mstch {
|
||||||
|
|
||||||
class render_section: public boost::static_visitor<std::string> {
|
class render_section {
|
||||||
public:
|
public:
|
||||||
enum class flag { none, keep_array };
|
enum class flag { none, keep_array };
|
||||||
render_section(
|
render_section(render_context& ctx,
|
||||||
render_context& ctx,
|
const template_type& section,
|
||||||
const template_type& section,
|
const delim_type& delims,
|
||||||
const delim_type& delims,
|
flag p_flag = flag::none)
|
||||||
flag p_flag = flag::none):
|
: m_ctx(ctx), m_section(section), m_delims(delims), m_flag(p_flag)
|
||||||
m_ctx(ctx), m_section(section), m_delims(delims), m_flag(p_flag)
|
{}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
std::string operator()(const T& t) const {
|
std::string operator()(const T& t) const {
|
||||||
return render_context::push(m_ctx, t).render(m_section);
|
return render_context::push(m_ctx, t).render(m_section);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string operator()(const lambda& fun) const {
|
std::string operator()(const lambda_wrapper& fun) const {
|
||||||
std::string section_str;
|
std::string section_str;
|
||||||
for (auto& token: m_section)
|
for (auto& token : m_section)
|
||||||
section_str += token.raw();
|
section_str += token.raw();
|
||||||
template_type interpreted{fun([this](const mstch::node& n) {
|
template_type interpreted{fun.values(
|
||||||
return visit(render_node(m_ctx), n);
|
[this](const mstch::node& n) {
|
||||||
}, section_str), m_delims};
|
return visit(render_node(m_ctx), n);
|
||||||
return render_context::push(m_ctx).render(interpreted);
|
},
|
||||||
}
|
section_str),
|
||||||
|
m_delims};
|
||||||
|
return render_context::push(m_ctx).render(interpreted);
|
||||||
|
}
|
||||||
|
|
||||||
std::string operator()(const array& array) const {
|
std::string operator()(const array_wrapper& array) const {
|
||||||
std::string out;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
if (m_flag == flag::keep_array)
|
||||||
render_context& m_ctx;
|
return render_context::push(m_ctx, array).render(m_section);
|
||||||
const template_type& m_section;
|
|
||||||
const delim_type& m_delims;
|
for (auto& item : array.values)
|
||||||
flag m_flag;
|
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{
|
const mstch::node ampersand_escape_data =
|
||||||
{"message", std::string{"Some <code>"}}
|
mstch::map_wrapper{{{"message", std::string{"Some <code>"}}}};
|
||||||
};
|
|
||||||
|
@ -1,4 +1,2 @@
|
|||||||
const auto apostrophe_data = mstch::map{
|
const mstch::node apostrophe_data =
|
||||||
{"apos", std::string{"'"}},
|
mstch::map_wrapper{{{"apos", std::string{"'"}}, {"control", std::string{"X"}}}};
|
||||||
{"control", std::string{"X"}}
|
|
||||||
};
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
const auto array_of_strings_data = mstch::map{
|
const mstch::node array_of_strings_data = mstch::map_wrapper{
|
||||||
{"array_of_strings", mstch::array{std::string{"hello"}, std::string{"world"}}}
|
{{"array_of_strings",
|
||||||
};
|
mstch::array_wrapper{{std::string{"hello"}, std::string{"world"}}}}}};
|
||||||
|
@ -1,3 +1 @@
|
|||||||
const auto backslashes_data = mstch::map{
|
const mstch::node backslashes_data = mstch::map_wrapper{{{"value", std::string{"\\abc"}}}};
|
||||||
{"value", std::string{"\\abc"}}
|
|
||||||
};
|
|
||||||
|
@ -1,3 +1,2 @@
|
|||||||
const auto bug_11_eating_whitespace_data = mstch::map{
|
const mstch::node bug_11_eating_whitespace_data =
|
||||||
{"tag", std::string{"yo"}}
|
mstch::map_wrapper{{{"tag", std::string{"yo"}}}};
|
||||||
};
|
|
||||||
|
@ -1,3 +1,2 @@
|
|||||||
const auto bug_length_property_data = mstch::map{
|
const mstch::node bug_length_property_data =
|
||||||
{"length", std::string{"hello"}}
|
mstch::map_wrapper{{{"length", std::string{"hello"}}}};
|
||||||
};
|
|
||||||
|
@ -1,4 +1,2 @@
|
|||||||
const mstch::node changing_delimiters_data = mstch::map{
|
const mstch::node changing_delimiters_data = mstch::map_wrapper{
|
||||||
{"foo", std::string{"foooooooooooooo"}},
|
{{"foo", std::string{"foooooooooooooo"}}, {"bar", std::string{"<b>bar!</b>"}}}};
|
||||||
{"bar", std::string{"<b>bar!</b>"}}
|
|
||||||
};
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
const mstch::node comments_data = mstch::map{
|
const mstch::node comments_data =
|
||||||
{"title", mstch::lambda{[]()->mstch::node{return std::string{"A Comedy of Errors"};}}}
|
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:
|
private:
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
bool m_current;
|
bool m_current;
|
||||||
std::string m_url;
|
std::string m_url;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
complex_item(const std::string& name, bool current, const std::string& url):
|
complex_item(const std::string& name, bool current, const std::string& url)
|
||||||
m_name(name), m_current(current), m_url(url)
|
: m_name(name), m_current(current), m_url(url)
|
||||||
{
|
{
|
||||||
register_methods(this, std::map<std::string,mstch::node(complex_item::*)()>{
|
register_methods(this,
|
||||||
{"name", &complex_item::name}, {"current", &complex_item::current},
|
std::map<std::string, mstch::node (complex_item::*)()>{
|
||||||
{"url", &complex_item::url}, {"link", &complex_item::link}
|
{"name", &complex_item::name},
|
||||||
});
|
{"current", &complex_item::current},
|
||||||
}
|
{"url", &complex_item::url},
|
||||||
|
{"link", &complex_item::link}});
|
||||||
|
}
|
||||||
|
|
||||||
mstch::node current() {
|
mstch::node current() { return m_current; }
|
||||||
return m_current;
|
|
||||||
}
|
|
||||||
|
|
||||||
mstch::node url() {
|
mstch::node url() { return m_url; }
|
||||||
return m_url;
|
|
||||||
}
|
|
||||||
|
|
||||||
mstch::node name() {
|
mstch::node name() { return m_name; }
|
||||||
return m_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
mstch::node link() {
|
mstch::node link() { return !m_current; }
|
||||||
return !m_current;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class complex: public mstch::object {
|
class complex : public mstch::object {
|
||||||
private:
|
private:
|
||||||
std::string m_header;
|
std::string m_header;
|
||||||
mstch::array m_item;
|
mstch::array m_item;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
complex():
|
complex()
|
||||||
m_header("Colors"),
|
: m_header("Colors")
|
||||||
m_item(mstch::array{
|
, m_item(mstch::array{mstch::object_wrapper{
|
||||||
std::make_shared<complex_item>("red", true, "#Red"),
|
std::make_shared<complex_item>("red", true, "#Red")},
|
||||||
std::make_shared<complex_item>("green", false, "#Green"),
|
mstch::object_wrapper{
|
||||||
std::make_shared<complex_item>("blue", false, "#Blue")
|
std::make_shared<complex_item>("green", false, "#Green")},
|
||||||
})
|
mstch::object_wrapper{std::make_shared<complex_item>("blue",
|
||||||
{
|
false,
|
||||||
register_methods(this, std::map<std::string,mstch::node(complex::*)()>{
|
"#Blue")}})
|
||||||
{"header", &complex::header}, {"item", &complex::item},
|
{
|
||||||
{"list", &complex::list}, {"empty", &complex::empty}
|
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() {
|
mstch::node header() { return m_header; }
|
||||||
return m_header;
|
|
||||||
}
|
|
||||||
|
|
||||||
mstch::node item() {
|
mstch::node item() { return mstch::array_wrapper{m_item}; }
|
||||||
return m_item;
|
|
||||||
}
|
|
||||||
|
|
||||||
mstch::node list() {
|
mstch::node list() { return m_item.size() != 0; }
|
||||||
return m_item.size() != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
mstch::node empty() {
|
mstch::node empty() { return m_item.size() == 0; }
|
||||||
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{
|
const mstch::node context_lookup_data = mstch::map_wrapper{
|
||||||
{"outer", mstch::map{
|
{{"outer",
|
||||||
{"id", 1},
|
mstch::map_wrapper{{{"id", 1}, {"second", mstch::map_wrapper{{{"nothing", 2}}}}}}}}};
|
||||||
{"second", mstch::map{
|
|
||||||
{"nothing", 2}
|
|
||||||
}}
|
|
||||||
}}
|
|
||||||
};
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
const mstch::node delimiters_data = mstch::map{
|
const mstch::node delimiters_data = mstch::map_wrapper{
|
||||||
{"first", std::string{"It worked the first time."}},
|
{{"first", std::string{"It worked the first time."}},
|
||||||
{"second", std::string{"And it worked the second time."}},
|
{"second", std::string{"And it worked the second time."}},
|
||||||
{"third", std::string{"Then, surprisingly, it worked the third time."}},
|
{"third", std::string{"Then, surprisingly, it worked the third time."}},
|
||||||
{"fourth", std::string{"Fourth time also fine!."}}
|
{"fourth", std::string{"Fourth time also fine!."}}}};
|
||||||
};
|
|
||||||
|
@ -1,4 +1,2 @@
|
|||||||
const auto disappearing_whitespace_data = mstch::map{
|
const mstch::node disappearing_whitespace_data =
|
||||||
{"bedrooms", true},
|
mstch::map_wrapper{{{"bedrooms", true}, {"total", 1}}};
|
||||||
{"total", 1}
|
|
||||||
};
|
|
||||||
|
@ -1,34 +1,32 @@
|
|||||||
class dot_notation_price: public mstch::object {
|
class dot_notation_price : public mstch::object {
|
||||||
private:
|
private:
|
||||||
int m_value;
|
int m_value;
|
||||||
mstch::map m_currency;
|
mstch::map m_currency;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
dot_notation_price():
|
dot_notation_price()
|
||||||
m_value(200), m_currency(mstch::map{{"symbol", std::string{"$"}}, {"name", std::string{"USD"}}})
|
: 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},
|
register_methods(this,
|
||||||
{"vat", &dot_notation_price::vat},
|
std::map<std::string, mstch::node (dot_notation_price::*)()>{
|
||||||
{"currency", &dot_notation_price::currency}});
|
{"value", &dot_notation_price::value},
|
||||||
}
|
{"vat", &dot_notation_price::vat},
|
||||||
|
{"currency", &dot_notation_price::currency}});
|
||||||
|
}
|
||||||
|
|
||||||
mstch::node value() {
|
mstch::node value() { return m_value; }
|
||||||
return m_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
mstch::node vat() {
|
mstch::node vat() { return m_value * 0.2; }
|
||||||
return m_value * 0.2;
|
|
||||||
}
|
|
||||||
|
|
||||||
mstch::node currency() {
|
mstch::node currency() { return mstch::map_wrapper{m_currency}; }
|
||||||
return m_currency;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto dot_notation_data = mstch::map{
|
const mstch::node dot_notation_data = mstch::map_wrapper{
|
||||||
{"name", std::string{"A Book"}},
|
{{"name", std::string{"A Book"}},
|
||||||
{"authors", mstch::array{std::string{"John Power"}, std::string{"Jamie Walsh"}}},
|
{"authors",
|
||||||
{"price", std::make_shared<dot_notation_price>()},
|
mstch::array_wrapper{{std::string{"John Power"}, std::string{"Jamie Walsh"}}}},
|
||||||
{"availability", mstch::map{{"status", true}, {"text", std::string{"In Stock"}}}},
|
{"price", mstch::object_wrapper{std::make_shared<dot_notation_price>()}},
|
||||||
{"truthy", mstch::map{{"zero", 0}, {"notTrue", false}}}
|
{"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{
|
const mstch::node double_render_data = mstch::map_wrapper{
|
||||||
{"foo", true},
|
{{"foo", true}, {"bar", std::string{"{{win}}"}}, {"win", std::string{"FAIL"}}}};
|
||||||
{"bar", std::string{"{{win}}"}},
|
|
||||||
{"win", std::string{"FAIL"}}
|
|
||||||
};
|
|
||||||
|
@ -1,3 +1 @@
|
|||||||
const auto empty_list_data = mstch::map{
|
const mstch::node empty_list_data = mstch::map_wrapper{{{"jobs", mstch::array_wrapper{}}}};
|
||||||
{"jobs", mstch::array{}}
|
|
||||||
};
|
|
||||||
|
@ -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{
|
#include "mstch/mstch.hpp"
|
||||||
{"description", std::string{"That is all!"}},
|
|
||||||
{"child", mstch::map{
|
const auto empty_string_data =
|
||||||
{"description", std::string{""}}
|
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{
|
const mstch::node error_eof_in_section_data = mstch::map_wrapper{
|
||||||
{"hello", mstch::array{std::string{"a"}, std::string{"b"}}}
|
{{"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{
|
const mstch::node error_not_found_data = mstch::map_wrapper{{{"bar", 2}}};
|
||||||
{"bar", 2}
|
|
||||||
};
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
const mstch::node escaped_data = mstch::map{
|
const mstch::node escaped_data = mstch::map_wrapper{
|
||||||
{"title", mstch::lambda{[]()->mstch::node{ return std::string{"Bear > Shark"}; }}},
|
{{"title",
|
||||||
{"entities", mstch::lambda{[]()->mstch::node{ return std::string{"" \"'<>/"}; }}}
|
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{
|
const auto falsy_data = mstch::map_wrapper{{{"emptyString", std::string{""}},
|
||||||
{"emptyString", std::string{""}},
|
{"emptyArray", mstch::array_wrapper{}},
|
||||||
{"emptyArray", mstch::array{}},
|
{"zero", 0},
|
||||||
{"zero", 0},
|
{"null", mstch::node{}}}};
|
||||||
{"null", mstch::node{}}
|
|
||||||
};
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
const auto falsy_array_data = mstch::map{
|
const auto falsy_array_data = mstch::map_wrapper{
|
||||||
{"list", mstch::array{
|
{{"list",
|
||||||
mstch::array{std::string{""}, std::string{"emptyString"}},
|
mstch::array_wrapper{
|
||||||
mstch::array{mstch::array{}, std::string{"emptyArray"}},
|
{mstch::array_wrapper{{std::string{""}, std::string{"emptyString"}}},
|
||||||
mstch::array{0, std::string{"zero"}},
|
mstch::array_wrapper{{mstch::array_wrapper{}, std::string{"emptyArray"}}},
|
||||||
mstch::array{mstch::node{}, std::string{"null"}}}
|
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{
|
const auto grandparent_context_data = mstch::map_wrapper{
|
||||||
{"grand_parent_id", std::string{"grand_parent1"}},
|
{{"grand_parent_id", std::string{"grand_parent1"}},
|
||||||
{"parent_contexts", mstch::array{
|
{"parent_contexts",
|
||||||
mstch::map{
|
mstch::array_wrapper{
|
||||||
{"parent_id", std::string{"parent1"}},
|
{mstch::map_wrapper{
|
||||||
{"child_contexts", mstch::array{
|
{{"parent_id", std::string{"parent1"}},
|
||||||
mstch::map{{"child_id", std::string{"parent1-child1"}}},
|
{"child_contexts",
|
||||||
mstch::map{{"child_id", std::string{"parent1-child2"}}}
|
mstch::array_wrapper{
|
||||||
}}
|
{mstch::map_wrapper{
|
||||||
},
|
{{"child_id", std::string{"parent1-child1"}}}},
|
||||||
mstch::map{
|
mstch::map_wrapper{
|
||||||
{"parent_id", std::string{"parent2"}},
|
{{"child_id",
|
||||||
{"child_contexts", mstch::array{
|
std::string{"parent1-child2"}}}}}}}}},
|
||||||
mstch::map{{"child_id", std::string{"parent2-child1"}}},
|
mstch::map_wrapper{
|
||||||
mstch::map{{"child_id", std::string{"parent2-child2"}}}
|
{{"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 {
|
class higher_order_sections : public mstch::object {
|
||||||
private:
|
private:
|
||||||
std::string m_helper;
|
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}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
mstch::node name() {
|
public:
|
||||||
return std::string{"Tater"};
|
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() {
|
mstch::node name() { return std::string{"Tater"}; }
|
||||||
return m_helper;
|
|
||||||
}
|
|
||||||
|
|
||||||
mstch::node bolder() {
|
mstch::node helper() { return m_helper; }
|
||||||
return mstch::lambda{[this](const std::string& text) -> mstch::node {
|
|
||||||
return "<b>" + text + "</b> " + 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{
|
const auto implicit_iterator_data = mstch::map_wrapper{
|
||||||
{"data", mstch::map{
|
{{"data",
|
||||||
{"author", mstch::map{
|
mstch::map_wrapper{{{"author",
|
||||||
{"twitter_id", 819606},
|
mstch::map_wrapper{{{"twitter_id", 819606},
|
||||||
{"name", std::string{"janl"}}
|
{"name", std::string{"janl"}}}}}}}}}};
|
||||||
}}
|
|
||||||
}}
|
|
||||||
};
|
|
||||||
|
@ -1,3 +1,2 @@
|
|||||||
const auto included_tag_data = mstch::map{
|
const mstch::node included_tag_data =
|
||||||
{"html", std::string{"I like {{mustache}}"}}
|
mstch::map_wrapper{{{"html", std::string{"I like {{mustache}}"}}}};
|
||||||
};
|
|
||||||
|
@ -1,3 +1 @@
|
|||||||
const auto inverted_section_data = mstch::map{
|
const auto inverted_section_data = mstch::map_wrapper{{{"repos", mstch::array_wrapper{}}}};
|
||||||
{"repos", mstch::array{}}
|
|
||||||
};
|
|
||||||
|
@ -1,5 +1,2 @@
|
|||||||
const auto keys_with_questionmarks_data = mstch::map{
|
const auto keys_with_questionmarks_data =
|
||||||
{"person?", mstch::map{
|
mstch::map_wrapper{{{"person?", mstch::map_wrapper{{{"name", std::string{"Jon"}}}}}}};
|
||||||
{"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{
|
const mstch::node nested_higher_order_sections_data = mstch::map_wrapper{
|
||||||
{"bold", mstch::lambda{[](const std::string& text) -> mstch::node {
|
{{"bold", mstch::lambda_wrapper{{[](const std::string& text) -> mstch::node {
|
||||||
return std::string{"<b>"} + text + std::string{"</b>"};
|
return std::string{"<b>"} + text + std::string{"</b>"};
|
||||||
}}},
|
}}}},
|
||||||
{"person", mstch::map{{"name", std::string{"Jonas"}}}}
|
{"person", mstch::map_wrapper{{{"name", std::string{"Jonas"}}}}}}};
|
||||||
};
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
const auto nested_iterating_data = mstch::map{
|
const mstch::node nested_iterating_data = mstch::map_wrapper{
|
||||||
{"inner", mstch::array{mstch::map{
|
{{"inner",
|
||||||
{"foo", std::string{"foo"}},
|
mstch::array_wrapper{
|
||||||
{"inner", mstch::array{mstch::map{
|
{mstch::map_wrapper{{{"foo", std::string{"foo"}},
|
||||||
{"bar", std::string{"bar"}}
|
{"inner",
|
||||||
}}}
|
mstch::array_wrapper{{mstch::map_wrapper{
|
||||||
}}}
|
{{"bar", std::string{"bar"}}}}}}}}}}}}}};
|
||||||
};
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
const auto nesting_data = mstch::map{
|
const mstch::node nesting_data = mstch::map_wrapper{
|
||||||
{"foo", mstch::array{
|
{{"foo",
|
||||||
mstch::map{{"a", mstch::map{{"b", 1}}}},
|
mstch::array_wrapper{
|
||||||
mstch::map{{"a", mstch::map{{"b", 2}}}},
|
{mstch::map_wrapper{{{"a", mstch::map_wrapper{{{"b", 1}}}}}},
|
||||||
mstch::map{{"a", mstch::map{{"b", 3}}}}
|
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{
|
const mstch::node nesting_same_name_data = mstch::map_wrapper{
|
||||||
{"items", mstch::array{
|
{{"items",
|
||||||
mstch::map{
|
mstch::array_wrapper{
|
||||||
{"name", std::string{"name"}},
|
{mstch::map_wrapper{{{"name", std::string{"name"}},
|
||||||
{"items", mstch::array{1, 2, 3, 4}}
|
{"items", mstch::array_wrapper{{1, 2, 3, 4}}}}}}}}}};
|
||||||
}
|
|
||||||
}}
|
|
||||||
};
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
const auto null_lookup_array_data = mstch::map{
|
const mstch::node null_lookup_array_data = mstch::map_wrapper{
|
||||||
{"name", std::string{"David"}},
|
{{"name", std::string{"David"}},
|
||||||
{"twitter", std::string{"@dasilvacontin"}},
|
{"twitter", std::string{"@dasilvacontin"}},
|
||||||
{"farray", mstch::array{
|
{"farray",
|
||||||
mstch::array{std::string{"Flor"}, std::string{"@florrts"}},
|
mstch::array_wrapper{{
|
||||||
mstch::array{std::string{"Miquel"}, mstch::node{}},
|
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{
|
const mstch::node null_lookup_object_data = mstch::map_wrapper{
|
||||||
{"name", std::string{"David"}},
|
{{"name", std::string{"David"}},
|
||||||
{"twitter", std::string{"@dasilvacontin"}},
|
{"twitter", std::string{"@dasilvacontin"}},
|
||||||
{"fobject", mstch::array{
|
{"fobject",
|
||||||
mstch::map{
|
mstch::array_wrapper{{{mstch::map_wrapper{{{"name", std::string{"Flor"}},
|
||||||
{"name", std::string{"Flor"}},
|
{"twitter", std::string{"@florrts"}}}}},
|
||||||
{"twitter", std::string{"@florrts"}}
|
mstch::map_wrapper{{{"name", std::string{"Miquel"}},
|
||||||
},
|
{"twitter", mstch::node{}}}}}}}}};
|
||||||
mstch::map{
|
|
||||||
{"name", std::string{"Miquel"}},
|
|
||||||
{"twitter", mstch::node{}}
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
};
|
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
const auto null_string_data = mstch::map{
|
const mstch::node null_string_data = mstch::map_wrapper{{{"name", std::string{"Elise"}},
|
||||||
{"name", std::string{"Elise"}},
|
{"glytch", true},
|
||||||
{"glytch", true},
|
{"binary", false},
|
||||||
{"binary", false},
|
{"value", mstch::node{}}}};
|
||||||
{"value", mstch::node{}}
|
|
||||||
};
|
|
||||||
|
@ -1,4 +1,2 @@
|
|||||||
const auto null_view_data = mstch::map{
|
const mstch::node null_view_data =
|
||||||
{"name", std::string{"Joe"}},
|
mstch::map_wrapper{{{"name", std::string{"Joe"}}, {"friends", mstch::node{}}}};
|
||||||
{"friends", mstch::node{}}
|
|
||||||
};
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
const auto partial_array_data = mstch::map{
|
const mstch::node partial_array_data = mstch::map_wrapper{
|
||||||
{"array", mstch::array{std::string{"1"}, std::string{"2"}, std::string{"3"}, std::string{"4"}}}
|
{{"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{
|
const mstch::node partial_array_of_partials_data = mstch::map_wrapper{
|
||||||
{"numbers", mstch::array{
|
{{"numbers",
|
||||||
mstch::map{{"i", std::string{"1"}}},
|
mstch::array_wrapper{{mstch::map_wrapper{{{"i", std::string{"1"}}}},
|
||||||
mstch::map{{"i", std::string{"2"}}},
|
mstch::map_wrapper{{{"i", std::string{"2"}}}},
|
||||||
mstch::map{{"i", std::string{"3"}}},
|
mstch::map_wrapper{{{"i", std::string{"3"}}}},
|
||||||
mstch::map{{"i", std::string{"4"}}}
|
mstch::map_wrapper{{{"i", std::string{"4"}}}}}}}}};
|
||||||
}}
|
|
||||||
};
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
const auto partial_array_of_partials_implicit_data = mstch::map{
|
const mstch::node partial_array_of_partials_implicit_data = mstch::map_wrapper{
|
||||||
{"numbers", mstch::array{std::string{"1"}, std::string{"2"}, std::string{"3"}, std::string{"4"}}}
|
{{"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{
|
const mstch::node partial_empty_data = mstch::map_wrapper{{{"foo", 1}}};
|
||||||
{"foo", 1}
|
|
||||||
};
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
const mstch::node partial_template_data = mstch::map{
|
const mstch::node partial_template_data = mstch::map_wrapper{{
|
||||||
{"title", mstch::lambda{[]()->mstch::node{ return std::string{"Welcome"}; }}},
|
{"title",
|
||||||
{"again", mstch::lambda{[]()->mstch::node{ return std::string{"Goodbye"}; }}},
|
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:
|
private:
|
||||||
int m_value;
|
int m_value;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
partial_whitespace(): m_value(10000) {
|
partial_whitespace() : m_value(10000) {
|
||||||
register_methods(this, std::map<std::string,mstch::node(partial_whitespace::*)()>{
|
register_methods(this,
|
||||||
{"greeting", &partial_whitespace::greeting},
|
std::map<std::string, mstch::node (partial_whitespace::*)()>{
|
||||||
{"farewell", &partial_whitespace::farewell},
|
{"greeting", &partial_whitespace::greeting},
|
||||||
{"name", &partial_whitespace::name},
|
{"farewell", &partial_whitespace::farewell},
|
||||||
{"value", &partial_whitespace::value},
|
{"name", &partial_whitespace::name},
|
||||||
{"taxed_value", &partial_whitespace::taxed_value},
|
{"value", &partial_whitespace::value},
|
||||||
{"in_ca", &partial_whitespace::in_ca}
|
{"taxed_value", &partial_whitespace::taxed_value},
|
||||||
});
|
{"in_ca", &partial_whitespace::in_ca}});
|
||||||
}
|
}
|
||||||
|
|
||||||
mstch::node greeting() {
|
mstch::node greeting() { return std::string{"Welcome"}; }
|
||||||
return std::string{"Welcome"};
|
|
||||||
}
|
|
||||||
|
|
||||||
mstch::node farewell() {
|
mstch::node farewell() { return std::string{"Fair enough, right?"}; }
|
||||||
return std::string{"Fair enough, right?"};
|
|
||||||
}
|
|
||||||
|
|
||||||
mstch::node name() {
|
mstch::node name() { return std::string{"Chris"}; }
|
||||||
return std::string{"Chris"};
|
|
||||||
}
|
|
||||||
|
|
||||||
mstch::node value() {
|
mstch::node value() { return m_value; }
|
||||||
return m_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
mstch::node taxed_value() {
|
mstch::node taxed_value() { return static_cast<int>(m_value - (m_value * 0.4)); }
|
||||||
return static_cast<int>(m_value - (m_value * 0.4));
|
|
||||||
}
|
|
||||||
|
|
||||||
mstch::node in_ca() {
|
mstch::node in_ca() { return true; }
|
||||||
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{
|
const mstch::node recursion_with_same_names_data = mstch::map_wrapper{
|
||||||
{"name", std::string{"name"}},
|
{{"name", std::string{"name"}},
|
||||||
{"description", std::string{"desc"}},
|
{"description", std::string{"desc"}},
|
||||||
{"terms", mstch::array{
|
{"terms",
|
||||||
mstch::map{{"name", std::string{"t1"}}, {"index", 0}},
|
mstch::array_wrapper{
|
||||||
mstch::map{{"name", std::string{"t2"}}, {"index", 1}}
|
{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{
|
const mstch::node reuse_of_enumerables_data = mstch::map_wrapper{
|
||||||
{"terms", mstch::array{
|
{{"terms",
|
||||||
mstch::map{{"name", std::string{"t1"}}, {"index", 0}},
|
mstch::array_wrapper{
|
||||||
mstch::map{{"name", std::string{"t2"}}, {"index", 1}}
|
{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{
|
const mstch::node section_as_context_data = mstch::map_wrapper{
|
||||||
{"a_object", mstch::map{
|
{{"a_object",
|
||||||
{"title", std::string{"this is an object"}},
|
mstch::map_wrapper{
|
||||||
{"description", std::string{"one of its attributes is a list"}},
|
{{"title", std::string{"this is an object"}},
|
||||||
{"a_list", mstch::array{
|
{"description", std::string{"one of its attributes is a list"}},
|
||||||
mstch::map{{"label", std::string{"listitem1"}}},
|
{"a_list",
|
||||||
mstch::map{{"label", std::string{"listitem2"}}}
|
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{
|
const mstch::node section_functions_in_partials_data = mstch::map_wrapper{
|
||||||
{"bold", mstch::lambda{[](const std::string& text) -> mstch::node {
|
{{"bold", mstch::lambda_wrapper{{[](const std::string& text) -> mstch::node {
|
||||||
return std::string{"<b>"} + text + std::string{"</b>"};
|
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{
|
const mstch::node string_as_context_data = mstch::map_wrapper{
|
||||||
{"a_string", std::string{"aa"}},
|
{{"a_string", std::string{"aa"}},
|
||||||
{"a_list", mstch::array{std::string{"a"},std::string{"b"},std::string{"c"}}}
|
{"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{
|
const mstch::node two_in_a_row_data = mstch::map_wrapper{
|
||||||
{"name", std::string{"Joe"}},
|
{{"name", std::string{"Joe"}}, {"greeting", std::string{"Welcome"}}}};
|
||||||
{"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{
|
const mstch::node unescaped_data =
|
||||||
{"title", mstch::lambda{[]()->mstch::node{ return std::string{"Bear > Shark"}; }}}
|
mstch::map_wrapper{{{"title", mstch::lambda_wrapper{{[]() -> mstch::node {
|
||||||
};
|
return std::string{"Bear > Shark"};
|
||||||
|
}}}}}};
|
||||||
|
@ -1,4 +1,2 @@
|
|||||||
const auto whitespace_data = mstch::map{
|
const mstch::node whitespace_data =
|
||||||
{"tag1", std::string{"Hello"}},
|
mstch::map_wrapper{{{"tag1", std::string{"Hello"}}, {"tag2", std::string{"World"}}}};
|
||||||
{"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 {
|
std::map<std::string, mstch::node> specs_lambdas{
|
||||||
{"Interpolation", mstch::lambda{[](const std::string&) -> mstch::node {
|
{"Interpolation", mstch::lambda_wrapper{{[](const std::string&) -> mstch::node {
|
||||||
return std::string{"world"};
|
return std::string{"world"};
|
||||||
}}},
|
}}}},
|
||||||
{"Interpolation - Expansion", mstch::lambda{[](const std::string&) -> mstch::node {
|
{"Interpolation - Expansion",
|
||||||
return std::string{"{{planet}}"};
|
mstch::lambda_wrapper{{[](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 - Alternate Delimiters",
|
||||||
}}},
|
mstch::lambda_wrapper{{[](const std::string&) -> mstch::node {
|
||||||
{"Interpolation - Multiple Calls", mstch::lambda{[](const std::string&) -> mstch::node {
|
return std::string{"|planet| => {{planet}}"};
|
||||||
static int calls = 0; return ++calls;
|
}}}},
|
||||||
}}},
|
{"Interpolation - Multiple Calls",
|
||||||
{"Escaping", mstch::lambda{[](const std::string&) -> mstch::node {
|
mstch::lambda_wrapper{{[](const std::string&) -> mstch::node {
|
||||||
return std::string{">"};
|
static int calls = 0;
|
||||||
}}},
|
return ++calls;
|
||||||
{"Section", mstch::lambda{[](const std::string& txt) -> mstch::node {
|
}}}},
|
||||||
return std::string{(txt == "{{x}}") ? "yes" : "no"};
|
{"Escaping", mstch::lambda_wrapper{{[](const std::string&) -> mstch::node {
|
||||||
}}},
|
return std::string{">"};
|
||||||
{"Section - Expansion", mstch::lambda{[](const std::string& txt) -> mstch::node {
|
}}}},
|
||||||
return txt + std::string{"{{planet}}"} + txt;
|
{"Section", mstch::lambda_wrapper{{[](const std::string& txt) -> mstch::node {
|
||||||
}}},
|
return std::string{(txt == "{{x}}") ? "yes" : "no"};
|
||||||
{"Section - Alternate Delimiters", mstch::lambda{[](const std::string& txt) -> mstch::node {
|
}}}},
|
||||||
return txt + std::string{"{{planet}} => |planet|"} + txt;
|
{"Section - Expansion",
|
||||||
}}},
|
mstch::lambda_wrapper{{[](const std::string& txt) -> mstch::node {
|
||||||
{"Section - Multiple Calls", mstch::lambda{[](const std::string& txt) -> mstch::node {
|
return txt + std::string{"{{planet}}"} + txt;
|
||||||
return "__" + txt + "__";
|
}}}},
|
||||||
}}},
|
{"Section - Alternate Delimiters",
|
||||||
{"Inverted Section", mstch::lambda{[](const std::string&) -> mstch::node {
|
mstch::lambda_wrapper{{[](const std::string& txt) -> mstch::node {
|
||||||
return false;
|
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
|
#define CATCH_CONFIG_MAIN
|
||||||
|
|
||||||
#include "catch.hpp"
|
#include "catch.hpp"
|
||||||
#include "rapidjson/document.h"
|
|
||||||
#include "mstch/mstch.hpp"
|
#include "mstch/mstch.hpp"
|
||||||
#include "test_context.hpp"
|
#include "rapidjson/document.h"
|
||||||
#include "test_data.hpp"
|
|
||||||
#include "specs_data.hpp"
|
#include "specs_data.hpp"
|
||||||
#include "specs_lambdas.hpp"
|
#include "specs_lambdas.hpp"
|
||||||
|
#include "test_context.hpp"
|
||||||
|
#include "test_data.hpp"
|
||||||
|
|
||||||
using namespace mstchtest;
|
using namespace mstchtest;
|
||||||
|
|
||||||
mstch::node to_value(const rapidjson::Value& val) {
|
mstch::node to_value(const rapidjson::Value& val) {
|
||||||
if (val.IsString())
|
if (val.IsString())
|
||||||
return std::string{val.GetString()};
|
return std::string{val.GetString()};
|
||||||
if (val.IsBool())
|
if (val.IsBool())
|
||||||
return val.GetBool();
|
return val.GetBool();
|
||||||
if (val.IsDouble())
|
if (val.IsDouble())
|
||||||
return val.GetDouble();
|
return val.GetDouble();
|
||||||
if (val.IsInt())
|
if (val.IsInt())
|
||||||
return val.GetInt();
|
return val.GetInt();
|
||||||
return mstch::node{};
|
return mstch::node{};
|
||||||
}
|
}
|
||||||
|
|
||||||
mstch::array to_array(const rapidjson::Value& val);
|
mstch::array to_array(const rapidjson::Value& val);
|
||||||
|
|
||||||
mstch::map to_object(const rapidjson::Value& val) {
|
mstch::map to_object(const rapidjson::Value& val) {
|
||||||
mstch::map ret;
|
mstch::map ret;
|
||||||
for (auto i = val.MemberBegin(); i != val.MemberEnd(); ++i) {
|
for (auto i = val.MemberBegin(); i != val.MemberEnd(); ++i) {
|
||||||
if (i->value.IsArray())
|
if (i->value.IsArray())
|
||||||
ret.insert(std::make_pair(i->name.GetString(), to_array(i->value)));
|
ret.insert(std::make_pair(i->name.GetString(),
|
||||||
else if (i->value.IsObject())
|
mstch::array_wrapper{to_array(i->value)}));
|
||||||
ret.insert(std::make_pair(i->name.GetString(), to_object(i->value)));
|
else if (i->value.IsObject())
|
||||||
else
|
ret.insert(std::make_pair(i->name.GetString(),
|
||||||
ret.insert(std::make_pair(i->name.GetString(), to_value(i->value)));
|
mstch::map_wrapper{to_object(i->value)}));
|
||||||
}
|
else
|
||||||
return ret;
|
ret.insert(std::make_pair(i->name.GetString(), to_value(i->value)));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
mstch::array to_array(const rapidjson::Value& val) {
|
mstch::array to_array(const rapidjson::Value& val) {
|
||||||
mstch::array ret;
|
mstch::array ret;
|
||||||
for (auto i = val.Begin(); i != val.End(); ++i) {
|
for (auto i = val.Begin(); i != val.End(); ++i) {
|
||||||
if (i->IsArray())
|
if (i->IsArray())
|
||||||
ret.push_back(to_array(*i));
|
ret.push_back(mstch::array_wrapper{to_array(*i)});
|
||||||
else if (i->IsObject())
|
else if (i->IsObject())
|
||||||
ret.push_back(to_object(*i));
|
ret.push_back(mstch::map_wrapper{to_object(*i)});
|
||||||
else
|
else
|
||||||
ret.push_back(to_value(*i));
|
ret.push_back(to_value(*i));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
mstch::node parse_with_rapidjson(const std::string& str) {
|
mstch::node parse_with_rapidjson(const std::string& str) {
|
||||||
rapidjson::Document doc;
|
rapidjson::Document doc;
|
||||||
doc.Parse(str.c_str());
|
doc.Parse(str.c_str());
|
||||||
return to_object(doc);
|
return mstch::map_wrapper{to_object(doc)};
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MSTCH_PARTIAL_TEST(x) TEST_CASE(#x) { \
|
#define MSTCH_PARTIAL_TEST(x) \
|
||||||
REQUIRE(x ## _txt == mstch::render(x ## _mustache, x ## _data, {{"partial", x ## _partial}})); \
|
TEST_CASE(#x) { \
|
||||||
}
|
REQUIRE(x##_txt == mstch::render(x##_mustache, x##_data, {{"partial", x##_partial}})); \
|
||||||
|
}
|
||||||
|
|
||||||
#define MSTCH_TEST(x) TEST_CASE(#x) { \
|
#define MSTCH_TEST(x) \
|
||||||
REQUIRE(x ## _txt == mstch::render(x ## _mustache, x ## _data)); \
|
TEST_CASE(#x) { REQUIRE(x##_txt == mstch::render(x##_mustache, x##_data)); }
|
||||||
}
|
|
||||||
|
|
||||||
#define SPECS_TEST(x) TEST_CASE("specs_" #x) { \
|
#define SPECS_TEST(x) \
|
||||||
using boost::get; \
|
TEST_CASE("specs_" #x) { \
|
||||||
auto data = parse_with_rapidjson(x ## _json); \
|
auto data = parse_with_rapidjson(x##_json); \
|
||||||
for (auto& test_item: get<mstch::array>(get<mstch::map>(data)["tests"])) {\
|
for (auto& test_item : std::get<mstch::array_wrapper>( \
|
||||||
auto test = get<mstch::map>(test_item); \
|
std::get<mstch::map_wrapper>(data).values["tests"]) \
|
||||||
std::map<std::string,std::string> partials; \
|
.values) { \
|
||||||
if (test.count("partials")) \
|
auto test = std::get<mstch::map_wrapper>(test_item).values; \
|
||||||
for (auto& partial_item: get<mstch::map>(test["partials"])) \
|
std::map<std::string, std::string> partials; \
|
||||||
partials.insert(std::make_pair(partial_item.first, get<std::string>(partial_item.second))); \
|
if (test.count("partials")) \
|
||||||
mstch::map context; \
|
for (auto& partial_item : \
|
||||||
for (auto& data_item: get<mstch::map>(test["data"])) \
|
std::get<mstch::map_wrapper>(test["partials"]).values) \
|
||||||
if (data_item.first == "lambda") \
|
partials.insert( \
|
||||||
context.insert(std::make_pair(data_item.first, specs_lambdas[get<std::string>(test["name"])])); \
|
std::make_pair(partial_item.first, \
|
||||||
else \
|
std::get<std::string>(partial_item.second))); \
|
||||||
context.insert(data_item); \
|
mstch::map context; \
|
||||||
SECTION(get<std::string>(test["name"])) \
|
for (auto& data_item : std::get<mstch::map_wrapper>(test["data"]).values) \
|
||||||
REQUIRE(mstch::render( \
|
if (data_item.first == "lambda") \
|
||||||
get<std::string>(test["template"]), \
|
context.insert(std::make_pair( \
|
||||||
context, partials) == \
|
data_item.first, \
|
||||||
get<std::string>(test["expected"])); \
|
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(ampersand_escape)
|
||||||
MSTCH_TEST(apostrophe)
|
MSTCH_TEST(apostrophe)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user