Compare commits

...

2 Commits

Author SHA1 Message Date
Sipka Dániel
9b27c7db88 no wrapper 2020-02-12 20:58:52 +01:00
Sipka Dániel
c2ec0d9ce8 boost -> std 2020-02-12 20:53:14 +01:00
84 changed files with 1489 additions and 1033 deletions

93
.clang-format Normal file
View 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
...

View File

@ -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
View 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>

View File

@ -1,12 +1,11 @@
#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 {
@ -24,9 +23,7 @@ class object_t {
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>
@ -46,13 +43,14 @@ class is_fun {
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);
@ -66,24 +64,18 @@ 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);
} }
@ -91,23 +83,47 @@ class lambda_t {
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;
};
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 node& root,
const std::map<std::string, std::string>& partials = const std::map<std::string, std::string>& partials =
std::map<std::string, std::string>()); std::map<std::string, std::string>());
} } // namespace mstch

View File

@ -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

View File

@ -7,8 +7,7 @@ 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)
{ {

View File

@ -6,8 +6,8 @@ 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);
@ -24,16 +24,14 @@ 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)
@ -50,9 +48,7 @@ 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; std::string output;
bool prev_eol = true; bool prev_eol = true;
for (auto& token : templt) { for (auto& token : templt) {
@ -64,9 +60,8 @@ std::string render_context::render(
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) : "";
} }

View File

@ -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"
@ -19,28 +19,24 @@ class render_context {
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: private:
render_context& m_context; render_context& m_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);
const mstch::node& get_node(const std::string& token); const mstch::node& get_node(const std::string& token);
std::string render( std::string render(const template_type& templt, const std::string& prefix = "");
const template_type& templt, const std::string& prefix = ""); std::string render_partial(const std::string& partial_name, const std::string& prefix);
std::string render_partial(
const std::string& partial_name, const std::string& prefix);
template<class T, class... Args> template<class T, class... Args>
void set_state(Args&&... args) { void set_state(Args&&... args) {
m_state.top() = std::unique_ptr<render_state>( m_state.top() = std::unique_ptr<render_state>(new T(std::forward<Args>(args)...));
new T(std::forward<Args>(args)...));
} }
private: private:
static const mstch::node null_node; static const mstch::node null_node;
const mstch::node& find_node( const mstch::node& find_node(const std::string& token,
const std::string& token,
std::list<node const*> current_nodes); std::list<node const*> current_nodes);
std::map<std::string, template_type> m_partials; std::map<std::string, template_type> m_partials;
std::deque<mstch::node> m_nodes; std::deque<mstch::node> m_nodes;
@ -48,4 +44,4 @@ class render_context {
std::stack<std::unique_ptr<render_state>> m_state; std::stack<std::unique_ptr<render_state>> m_state;
}; };
} } // namespace mstch

View File

@ -5,8 +5,8 @@
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)
{ {
} }

View File

@ -21,4 +21,4 @@ class in_section: public render_state {
int m_skipped_openings; int m_skipped_openings;
}; };
} } // namespace mstch

View File

@ -1,14 +1,12 @@
#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; using flag = render_node::flag;
switch (token.token_type()) { switch (token.token_type()) {
case token::type::section_open: case token::type::section_open:

View File

@ -9,4 +9,4 @@ class outside_section: public render_state {
std::string render(render_context& context, const token& token) override; std::string render(render_context& context, const token& token) override;
}; };
} } // namespace mstch

View File

@ -14,4 +14,4 @@ class 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

View File

@ -2,16 +2,14 @@
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); tokenize(str);
strip_whitespace(); strip_whitespace();
} }
@ -33,8 +31,7 @@ void template_type::tokenize(const std::string& tmp) {
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()) == '{' &&
@ -44,16 +41,15 @@ void template_type::tokenize(const std::string& tmp) {
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_beg = beg + open_pos + m_open.size() + 1;
auto tok_end = beg + close_pos - 1; auto tok_end = beg + close_pos - 1;
auto front_skip = first_not_ws(tok_beg, tok_end); auto front_skip = first_not_ws(tok_beg, tok_end);
@ -98,7 +94,6 @@ void template_type::strip_whitespace() {
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());
} }

View File

@ -27,4 +27,4 @@ class template_type {
void store_prefixes(std::vector<token>::iterator beg); void store_prefixes(std::vector<token>::iterator beg);
}; };
} } // namespace mstch

View File

@ -5,18 +5,25 @@ 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] == '=') {
@ -31,8 +38,7 @@ token::token(const std::string& str, std::size_t left, std::size_t right):
if (m_type != type::variable) if (m_type != type::variable)
c = first_not_ws(c + 1, str.end() - right); c = first_not_ws(c + 1, str.end() - right);
m_name = {c, first_not_ws(str.rbegin() + right, str.rend() - left) + 1}; m_name = {c, first_not_ws(str.rbegin() + right, str.rend() - left) + 1};
m_delims = {{str.begin(), str.begin() + left}, m_delims = {{str.begin(), str.begin() + left}, {str.end() - right, str.end()}};
{str.end() - right, str.end()}};
} }
} else { } else {
m_type = type::text; m_type = type::text;

View File

@ -9,8 +9,15 @@ 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,
section_close,
inverted_section_open,
unescaped_variable,
comment,
partial,
delimiter_change
}; };
token(const std::string& str, std::size_t left = 0, std::size_t right = 0); token(const std::string& str, std::size_t left = 0, std::size_t right = 0);
type token_type() const { return m_type; }; type token_type() const { return m_type; };
@ -36,4 +43,4 @@ class token {
type token_info(char c); type token_info(char c);
}; };
} } // namespace mstch

View File

@ -3,13 +3,15 @@
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 it;
return end; 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 --(rit.base());
return --(end.base()); return --(end.base());
} }
@ -31,13 +33,26 @@ std::string mstch::html_escape(const std::string& str) {
for (auto it = str.begin(); it != str.end(); ++it) for (auto it = str.begin(); it != str.end(); ++it)
switch (*it) { switch (*it) {
case '&': add_escape("&amp;", it); break; case '&':
case '\'': add_escape("&#39;", it); break; add_escape("&amp;", it);
case '"': add_escape("&quot;", it); break; break;
case '<': add_escape("&lt;", it); break; case '\'':
case '>': add_escape("&gt;", it); break; add_escape("&#39;", it);
case '/': add_escape("&#x2F;", it); break; break;
default: break; case '"':
add_escape("&quot;", it);
break;
case '<':
add_escape("&lt;", it);
break;
case '>':
add_escape("&gt;", it);
break;
case '/':
add_escape("&#x2F;", it);
break;
default:
break;
} }
return out + std::string{start, str.end()}; return out + std::string{start, str.end()};

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <string> #include <string>
#include <boost/variant/apply_visitor.hpp> #include <variant>
namespace mstch { namespace mstch {
@ -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

View File

@ -1,30 +1,27 @@
#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:
@ -32,4 +29,4 @@ class get_token: public boost::static_visitor<const mstch::node&> {
const mstch::node& m_node; const mstch::node& m_node;
}; };
} } // namespace mstch

View File

@ -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

View File

@ -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

View File

@ -1,30 +1,24 @@
#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;
@ -32,14 +26,12 @@ class render_node: public boost::static_visitor<std::string> {
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_wrapper& value) const {
template_type interpreted{value.values(
[this](const mstch::node& n) { return visit(render_node(m_ctx), n); })};
std::string operator()(const lambda& value) const {
template_type interpreted{value([this](const mstch::node& n) {
return visit(render_node(m_ctx), n);
})};
auto rendered = render_context::push(m_ctx).render(interpreted); auto rendered = render_context::push(m_ctx).render(interpreted);
return (m_flag == flag::escape_html) ? html_escape(rendered) : rendered; return (m_flag == flag::escape_html) ? html_escape(rendered) : rendered;
} }
@ -53,4 +45,4 @@ class render_node: public boost::static_visitor<std::string> {
flag m_flag; flag m_flag;
}; };
} } // namespace mstch

View File

@ -1,49 +1,49 @@
#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(
[this](const mstch::node& n) {
return visit(render_node(m_ctx), n); return visit(render_node(m_ctx), n);
}, section_str), m_delims}; },
section_str),
m_delims};
return render_context::push(m_ctx).render(interpreted); 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) if (m_flag == flag::keep_array)
return render_context::push(m_ctx, array).render(m_section); return render_context::push(m_ctx, array).render(m_section);
else
for (auto& item: array) for (auto& item : array.values)
out += visit(render_section( out += visit(render_section(m_ctx, m_section, m_delims, flag::keep_array), item);
m_ctx, m_section, m_delims, flag::keep_array), item);
return out; return out;
} }
@ -54,4 +54,4 @@ class render_section: public boost::static_visitor<std::string> {
flag m_flag; flag m_flag;
}; };
} } // namespace mstch

View File

@ -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>"}}}};
};

View File

@ -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"}}
};

View File

@ -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"}}}}}};

View File

@ -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"}}
};

View File

@ -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"}}}};
};

View File

@ -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"}}}};
};

View File

@ -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>"}}
};

View File

@ -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"};
}}}}}};

View File

@ -3,67 +3,59 @@ 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,
"#Blue")}})
{ {
register_methods(this, std::map<std::string,mstch::node(complex::*)()>{ register_methods(
{"header", &complex::header}, {"item", &complex::item}, this,
{"list", &complex::list}, {"empty", &complex::empty} 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>()};

View File

@ -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}
}}
}}
};

View File

@ -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!."}}}};
};

View File

@ -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}
};

View File

@ -2,33 +2,31 @@ 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::*)()>{ register_methods(this,
std::map<std::string, mstch::node (dot_notation_price::*)()>{
{"value", &dot_notation_price::value}, {"value", &dot_notation_price::value},
{"vat", &dot_notation_price::vat}, {"vat", &dot_notation_price::vat},
{"currency", &dot_notation_price::currency}}); {"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}}}}}};

View File

@ -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"}}
};

View File

@ -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{}}
};

View File

@ -1 +1 @@
const auto empty_sections_data = mstch::map{}; const mstch::node empty_sections_data = mstch::map_wrapper{{}};

View File

@ -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{""}}}}}}};
};

View File

@ -1 +1 @@
const auto empty_template_data = mstch::map{}; const mstch::node empty_template_data = mstch::map_wrapper{{}};

View File

@ -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"}}}}}};
};

View File

@ -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"}}}};

View File

@ -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}
};

View File

@ -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{"&quot; \"'<>/"}; }}} mstch::lambda_wrapper{{[]() -> mstch::node { return std::string{"Bear > Shark"}; }}}},
}; {"entities", mstch::lambda_wrapper{{[]() -> mstch::node {
return std::string{"&quot; \"'<>/"};
}}}}}};

View File

@ -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{}}}};
};

View File

@ -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"}}}}}}}};
};

View File

@ -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"}}}}}}}}}}}}}};

View File

@ -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: public:
higher_order_sections() : m_helper("To tinker?") { higher_order_sections() : m_helper("To tinker?") {
register_methods(this, std::map<std::string,mstch::node(higher_order_sections::*)()>{ register_methods(this,
std::map<std::string, mstch::node (higher_order_sections::*)()>{
{"name", &higher_order_sections::name}, {"name", &higher_order_sections::name},
{"helper", &higher_order_sections::helper}, {"helper", &higher_order_sections::helper},
{"bolder", &higher_order_sections::bolder} {"bolder", &higher_order_sections::bolder}});
});
} }
mstch::node name() { mstch::node name() { return std::string{"Tater"}; }
return std::string{"Tater"};
}
mstch::node helper() { mstch::node helper() { return m_helper; }
return m_helper;
}
mstch::node bolder() { mstch::node bolder() {
return mstch::lambda{[this](const std::string& text) -> mstch::node { return mstch::lambda_wrapper{{[this](const std::string& text) -> mstch::node {
return "<b>" + text + "</b> " + m_helper; 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>()};

View File

@ -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"}}}}}}}}}};
}}
}}
};

View File

@ -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}}"}}}};
};

View File

@ -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{}}
};

View File

@ -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"}}
}}
};

View File

@ -1 +1 @@
const auto multiline_comment_data = mstch::map{}; const mstch::node multiline_comment_data = mstch::map_wrapper{{}};

View File

@ -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"}}}};

View File

@ -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"}}}}}}};
};

View File

@ -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"}}}}}}}}}}}}}};
};

View File

@ -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}}}}}}}}}}};
};

View File

@ -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}}}}}}}}}};
}
}}
};

View File

@ -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{}}},
}; }}}}};

View File

@ -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{}}
}
}}
};

View File

@ -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{}}}};
};

View File

@ -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{}}
};

View File

@ -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"}}}}}};

View File

@ -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"}}}}}}}}};
}}
};

View File

@ -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"}}}}}};

View File

@ -1,3 +1 @@
const auto partial_empty_data = mstch::map{ const mstch::node partial_empty_data = mstch::map_wrapper{{{"foo", 1}}};
{"foo", 1}
};

View File

@ -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"}; }}}},
}};

View File

@ -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>()};

View File

@ -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,
std::map<std::string, mstch::node (partial_whitespace::*)()>{
{"greeting", &partial_whitespace::greeting}, {"greeting", &partial_whitespace::greeting},
{"farewell", &partial_whitespace::farewell}, {"farewell", &partial_whitespace::farewell},
{"name", &partial_whitespace::name}, {"name", &partial_whitespace::name},
{"value", &partial_whitespace::value}, {"value", &partial_whitespace::value},
{"taxed_value", &partial_whitespace::taxed_value}, {"taxed_value", &partial_whitespace::taxed_value},
{"in_ca", &partial_whitespace::in_ca} {"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>()};

View File

@ -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}}}}}}}};
};

View File

@ -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}}}}}}}};
};

View File

@ -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{
{{"title", std::string{"this is an object"}},
{"description", std::string{"one of its attributes is a list"}}, {"description", std::string{"one of its attributes is a list"}},
{"a_list", mstch::array{ {"a_list",
mstch::map{{"label", std::string{"listitem1"}}}, mstch::array_wrapper{
mstch::map{{"label", std::string{"listitem2"}}} {mstch::map_wrapper{{{"label", std::string{"listitem1"}}}},
}} mstch::map_wrapper{{{"label", std::string{"listitem2"}}}}}}}}}}}};
}}
};

View File

@ -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>"};
}}} }}}}}};
};

View File

@ -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>()};

View File

@ -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"}}}}}};

View File

@ -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"}}
};

View File

@ -1 +1 @@
const auto two_sections_data = mstch::map{}; const mstch::node two_sections_data = mstch::map_wrapper{{}};

View File

@ -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"};
}}}}}};

View File

@ -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"}}
};

View File

@ -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}}}}};

View File

@ -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",
mstch::lambda_wrapper{{[](const std::string&) -> mstch::node {
return std::string{"{{planet}}"}; return std::string{"{{planet}}"};
}}}, }}}},
{"Interpolation - Alternate Delimiters", mstch::lambda{[](const std::string&) -> mstch::node { {"Interpolation - Alternate Delimiters",
mstch::lambda_wrapper{{[](const std::string&) -> mstch::node {
return std::string{"|planet| => {{planet}}"}; return std::string{"|planet| => {{planet}}"};
}}}, }}}},
{"Interpolation - Multiple Calls", mstch::lambda{[](const std::string&) -> mstch::node { {"Interpolation - Multiple Calls",
static int calls = 0; return ++calls; mstch::lambda_wrapper{{[](const std::string&) -> mstch::node {
}}}, static int calls = 0;
{"Escaping", mstch::lambda{[](const std::string&) -> mstch::node { return ++calls;
}}}},
{"Escaping", mstch::lambda_wrapper{{[](const std::string&) -> mstch::node {
return std::string{">"}; return std::string{">"};
}}}, }}}},
{"Section", mstch::lambda{[](const std::string& txt) -> mstch::node { {"Section", mstch::lambda_wrapper{{[](const std::string& txt) -> mstch::node {
return std::string{(txt == "{{x}}") ? "yes" : "no"}; return std::string{(txt == "{{x}}") ? "yes" : "no"};
}}}, }}}},
{"Section - Expansion", mstch::lambda{[](const std::string& txt) -> mstch::node { {"Section - Expansion",
mstch::lambda_wrapper{{[](const std::string& txt) -> mstch::node {
return txt + std::string{"{{planet}}"} + txt; return txt + std::string{"{{planet}}"} + txt;
}}}, }}}},
{"Section - Alternate Delimiters", mstch::lambda{[](const std::string& txt) -> mstch::node { {"Section - Alternate Delimiters",
mstch::lambda_wrapper{{[](const std::string& txt) -> mstch::node {
return txt + std::string{"{{planet}} => |planet|"} + txt; return txt + std::string{"{{planet}} => |planet|"} + txt;
}}}, }}}},
{"Section - Multiple Calls", mstch::lambda{[](const std::string& txt) -> mstch::node { {"Section - Multiple Calls",
return "__" + txt + "__"; mstch::lambda_wrapper{
}}}, {[](const std::string& txt) -> mstch::node { return "__" + txt + "__"; }}}},
{"Inverted Section", mstch::lambda{[](const std::string&) -> mstch::node { {"Inverted Section",
return false; mstch::lambda_wrapper{{[](const std::string&) -> mstch::node { return false; }}}}};
}}}
};

View File

@ -1,12 +1,12 @@
#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;
@ -28,9 +28,11 @@ 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(),
mstch::array_wrapper{to_array(i->value)}));
else if (i->value.IsObject()) else if (i->value.IsObject())
ret.insert(std::make_pair(i->name.GetString(), to_object(i->value))); ret.insert(std::make_pair(i->name.GetString(),
mstch::map_wrapper{to_object(i->value)}));
else else
ret.insert(std::make_pair(i->name.GetString(), to_value(i->value))); ret.insert(std::make_pair(i->name.GetString(), to_value(i->value)));
} }
@ -41,9 +43,9 @@ 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));
} }
@ -53,37 +55,43 @@ mstch::array to_array(const rapidjson::Value& val) {
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) \
TEST_CASE(#x) { \
REQUIRE(x##_txt == mstch::render(x##_mustache, x##_data, {{"partial", x##_partial}})); \ 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"]) \
.values) { \
auto test = std::get<mstch::map_wrapper>(test_item).values; \
std::map<std::string, std::string> partials; \ std::map<std::string, std::string> partials; \
if (test.count("partials")) \ if (test.count("partials")) \
for (auto& partial_item: get<mstch::map>(test["partials"])) \ for (auto& partial_item : \
partials.insert(std::make_pair(partial_item.first, get<std::string>(partial_item.second))); \ std::get<mstch::map_wrapper>(test["partials"]).values) \
partials.insert( \
std::make_pair(partial_item.first, \
std::get<std::string>(partial_item.second))); \
mstch::map context; \ mstch::map context; \
for (auto& data_item: get<mstch::map>(test["data"])) \ for (auto& data_item : std::get<mstch::map_wrapper>(test["data"]).values) \
if (data_item.first == "lambda") \ if (data_item.first == "lambda") \
context.insert(std::make_pair(data_item.first, specs_lambdas[get<std::string>(test["name"])])); \ context.insert(std::make_pair( \
data_item.first, \
specs_lambdas[std::get<std::string>(test["name"])])); \
else \ else \
context.insert(data_item); \ context.insert(data_item); \
SECTION(get<std::string>(test["name"])) \ SECTION(std::get<std::string>(test["name"])) \
REQUIRE(mstch::render( \ REQUIRE(mstch::render(std::get<std::string>(test["template"]), \
get<std::string>(test["template"]), \ mstch::map_wrapper{context}, \
context, partials) == \ partials) == std::get<std::string>(test["expected"])); \
get<std::string>(test["expected"])); \
} \ } \
} }