Compare commits

...

14 Commits

Author SHA1 Message Date
21ca1f638b chore: format 2026-05-07 17:49:47 +04:00
Abdüssamet ERSOYLU
2b2a0df933 Merge pull request #9 from sametersoylu/refaction
feat: add reference capabilities to positional arguments. use existing
2026-05-05 12:01:17 +04:00
c067bbca38 update: example to display capturing capability via positional args. 2026-05-05 11:58:50 +04:00
54415f9527 feat: add reference capabilities to positional arguments. use existing
v2 api to capture reference arguments.
2026-05-05 11:57:36 +04:00
96fdbb5f00 chore: remove idea 2026-05-05 11:48:12 +04:00
Abdüssamet ERSOYLU
7fa218b7f3 Merge pull request #8 from sametersoylu/v3
V3
2026-05-05 11:45:43 +04:00
1c63622fd8 chore: update readme.md 2026-05-05 11:44:18 +04:00
1479892e7b chore: update todo. 2026-05-05 11:27:48 +04:00
708f63a00d feat: implement reference capture mode. 2026-05-05 11:20:53 +04:00
faf1715ee3 chore: remove compile commands 2026-05-05 10:38:19 +04:00
05c2f782b1 chore: demontrate concat. 2026-05-05 10:36:24 +04:00
7caeb20dfa feat: add compile time concatting capabilities for string building in
parsing traits for hints.
2026-05-05 10:36:12 +04:00
e1d72aaea7 chore: initial examples folder. 2026-05-04 13:52:08 +04:00
81a85149b4 feat: new argument builder. base for ref. 2026-05-04 13:51:54 +04:00
26 changed files with 953 additions and 1515 deletions

1
.gitignore vendored
View File

@@ -3,3 +3,4 @@ build
.vscode .vscode
.vs .vs
.cache .cache
.idea

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="CPP_MODULE" version="4">
<component name="NewModuleRootManager">
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

344
.idea/editor.xml generated
View File

@@ -1,344 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="BackendCodeEditorSettings">
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CDeclarationWithImplicitIntType/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CommentTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConstevalIfIsAlwaysConstant/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAbstractClassWithoutSpecifier/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAbstractFinalClass/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAbstractVirtualFunctionCallInCtor/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAccessSpecifierWithNoDeclarations/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAwaiterTypeIsNotClass/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBooleanIncrementExpression/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatBadCode/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatLegacyCode/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatMixedArgs/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatTooFewArgs/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatTooManyArgs/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCStyleCast/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCVQualifierCanNotBeAppliedToReference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassCanBeFinal/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassIsIncomplete/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeedsConstructorBecauseOfUninitializedMember/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCompileTimeConstantCanBeReplacedWithBooleanConstant/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConceptNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConditionalExpressionCanBeSimplified/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConstParameterInDeclaration/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConstValueFunctionReturnType/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCoroutineCallResolveError/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAArrayIndexOutOfBounds/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantConditions/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantFunctionResult/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantParameter/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFADeletedPointer/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAEndlessLoop/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAInfiniteRecursion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAInvalidatedMemory/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALocalValueEscapesFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALocalValueEscapesScope/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALoopConditionNotUpdated/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAMemoryLeak/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFANotInitializedField/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFANullDereference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFATimeOver/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnreachableCode/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnreachableFunctionCall/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnreadVariable/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnusedValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclarationHidesLocal/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclarationHidesUncapturedLocal/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclarationSpecifierWithoutDeclarators/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorDisambiguatedAsFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorUsedBeforeInitialization/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultCaseNotHandledInSwitchStatement/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultInitializationWithNoUserConstructor/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultIsUsedAsIdentifier/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultedSpecialMemberFunctionIsImplicitlyDeleted/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeletingVoidPointer/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDependentTemplateWithoutTemplateKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDependentTypeWithoutTypenameKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeprecatedEntity/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeprecatedOverridenMethod/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeprecatedRegisterStorageClassSpecifier/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDereferenceOperatorLimitExceeded/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDiscardedPostfixOperatorResult/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenSyntaxError/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenUndocumentedParameter/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenUnresolvedReference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEmptyDeclaration/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceCVQualifiersOrder/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceCVQualifiersPlacement/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceDoStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceForStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceFunctionDeclarationStyle/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceIfStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceNestedNamespacesStyle/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceOverridingDestructorStyle/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceOverridingFunctionStyle/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceTypeAliasCodeStyle/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceWhileStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEntityAssignedButNoRead/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEntityUsedOnlyInUnevaluatedContext/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnumeratorNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEqualOperandsInBinaryExpression/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEvaluationFailure/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppExplicitSpecializationInNonNamespaceScope/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppExpressionWithoutSideEffects/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFinalFunctionInFinalClass/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFinalNonOverridingVirtualFunction/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppForLoopCanBeReplacedWithWhile/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppForwardEnumDeclarationWithoutUnderlyingType/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionDoesntReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionIsNotImplemented/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionResultShouldBeUsed/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionalStyleCast/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppHeaderHasBeenAlreadyIncluded/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppHiddenFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppHidingFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIdenticalOperandsInBinaryExpression/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIfCanBeReplacedByConstexprIf/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppImplicitDefaultConstructorNotAvailable/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIncompatiblePointerConversion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIncompleteSwitchStatement/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppInconsistentNaming/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIntegralToPointerConversion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppInvalidLineContinuation/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppJoinDeclarationAndAssignment/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLambdaCaptureNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableMayBeConst/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableWithNonTrivialDtorIsNeverUsed/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLongFloat/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberFunctionMayBeConst/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberFunctionMayBeStatic/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberInitializersOrder/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMismatchedClassTags/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingIncludeGuard/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingKeywordThrow/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppModulePartitionWithSeveralPartitionUnits/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtAddressOfClassRValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtBindingRValueToLvalueReference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtCopyElisionInCopyInitDeclarator/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtDoubleUserConversionInCopyInit/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtNotInitializedStaticConstLocalVar/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtReinterpretCastFromNullptr/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMultiCharacterLiteral/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMultiCharacterWideLiteral/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMustBePublicVirtualToImplementInterface/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMutableSpecifierOnReferenceMember/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNoDiscardExpression/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNodiscardFunctionWithoutReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExceptionSafeResourceAcquisition/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExplicitConversionOperator/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExplicitConvertingConstructor/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonInlineFunctionDefinitionInHeaderFile/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonInlineVariableDefinitionInHeaderFile/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNotAllPathsReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppObjectMemberMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppOutParameterMustBeWritten/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterMayBeConst/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterMayBeConstPtrOrRef/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterNamesMismatch/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterNeverUsed/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPassValueParameterByConstReference/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPointerConversionDropsQualifiers/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPointerToIntegralConversion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPolymorphicClassWithNonVirtualPublicDestructor/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyErroneousEmptyStatements/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyUninitializedMember/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyUnintendedObjectSlicing/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrecompiledHeaderIsNotIncluded/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrecompiledHeaderNotFound/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfBadFormat/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfExtraArg/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfMissedArg/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfRiskyFormat/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrivateSpecialMemberFunctionIsNotImplemented/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRangeBasedForIncompatibleReference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedefinitionOfDefaultArgumentInOverrideFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantAccessSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantBaseClassAccessSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantBaseClassInitializer/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantBooleanExpressionArgument/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantCastExpression/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantComplexityInComparison/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantConditionalExpression/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantConstSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantControlFlowJump/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantDereferencingAndTakingAddress/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantElaboratedTypeSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantElseKeyword/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantElseKeywordInsideCompoundStatement/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantEmptyDeclaration/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantEmptyStatement/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantExportKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantFwdClassOrEnumSpecifier/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantInlineSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantLambdaParameterList/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantMemberInitializer/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantNamespaceDefinition/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantParentheses/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantQualifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantQualifierADL/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantStaticSpecifierOnMemberAllocationFunction/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantStaticSpecifierOnThreadLocalLocalVariable/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTemplateArguments/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTemplateKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTypenameKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantVoidArgumentList/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantZeroInitializerInAggregateInitialization/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReinterpretCastFromVoidPtr/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRemoveRedundantBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReplaceMemsetWithZeroInitialization/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReplaceTieWithStructuredBinding/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReturnNoValueInNonVoidFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSmartPointerVsMakeFunction/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSomeObjectMembersMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSpecialFunctionWithoutNoexceptSpecification/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticAssertFailure/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticDataMemberInUnnamedStruct/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticSpecifierOnAnonymousNamespaceMember/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStringLiteralToCharPointerConversion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTabsAreDisallowed/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateArgumentsCanBeDeduced/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateParameterNeverUsed/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateParameterShadowing/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppThrowExpressionCanBeReplacedWithRethrow/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTooWideScope/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTooWideScopeInitStatement/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTypeAliasNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUninitializedDependentBaseClass/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUninitializedNonStaticDataMember/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnionMemberOfReferenceType/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnmatchedPragmaEndRegionDirective/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnmatchedPragmaRegionDirective/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnnamedNamespaceInHeaderFile/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnnecessaryWhitespace/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnsignedZeroComparison/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnusedIncludeDirective/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAlgorithmWithCount/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAssociativeContains/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAuto/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAutoForNumeric/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseElementsView/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseEraseAlgorithm/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseFamiliarTemplateSyntaxForGenericLambdas/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseRangeAlgorithm/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseStdSize/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseStructuredBinding/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseTypeTraitAlias/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUserDefinedLiteralSuffixDoesNotStartWithUnderscore/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUsingResultOfAssignmentAsCondition/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVariableCanBeMadeConstexpr/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVirtualFunctionCallInsideCtor/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVirtualFunctionInFinalClass/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVolatileParameterInDeclaration/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppWarningDirective/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppWrongIncludesOrder/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppWrongSlashesInIncludeDirective/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppZeroConstantCanBeReplacedWithNullptr/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppZeroValuedExpressionUsedAsNullPointer/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=IdentifierTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=IfStdIsConstantEvaluatedCanBeReplaced/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=StdIsConstantEvaluatedWillAlwaysEvaluateToConstant/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringLiteralTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppClangFormat/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_ARGUMENT/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_BINARY_EXPRESSIONS_CHAIN/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_CALLS_CHAIN/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXPRESSION/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXTENDS_LIST/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_FOR_STMT/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_PARAMETER/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_ARGUMENT/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_PARAMETER/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTIPLE_DECLARATION/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_TERNARY/@EntryValue" value="ALIGN_ALL" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_CLASS_DEFINITION/@EntryValue" value="1" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_DECLARATIONS/@EntryValue" value="0" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DECLARATION/@EntryValue" value="1" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DEFINITION/@EntryValue" value="1" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BREAK_TEMPLATE_DECLARATION/@EntryValue" value="LINE_BREAK" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CASE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CONTINUOUS_LINE_INDENT/@EntryValue" value="Double" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_ACCESS_SPECIFIERS_FROM_CLASS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CASE_FROM_SWITCH/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CLASS_MEMBERS_FROM_ACCESS_SPECIFIERS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_COMMENT/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_SIZE/@EntryValue" value="4" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_STYLE/@EntryValue" value="Space" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INITIALIZER_BRACES/@EntryValue" value="END_OF_LINE_NO_SPACE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INT_ALIGN_EQ/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INVOCABLE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_CODE/@EntryValue" value="2" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue" value="2" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_USER_LINEBREAKS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/LINE_BREAK_AFTER_COLON_IN_MEMBER_INITIALIZER_LISTS/@EntryValue" value="ON_SINGLE_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/MEMBER_INITIALIZER_LIST_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_INDENTATION/@EntryValue" value="All" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/OTHER_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_CATCH_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_ELSE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_NAMESPACE_DEFINITIONS_ON_SAME_LINE/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_WHILE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SIMPLE_BLOCK_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_PARAMS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_COLON/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_SEMICOLON/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_METHOD/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_NESTED_DECLARATOR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_METHOD/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_UNARY_OPERATOR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_COLON/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_SEMICOLON/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_METHOD/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_METHOD/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BETWEEN_CLOSING_ANGLE_BRACKETS_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_ARRAY_ACCESS_BRACKETS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_DECLARATION_PARENTHESES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_BLOCKS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_METHOD_PARENTHESES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPECIAL_ELSE_IF_TREATMENT/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TAB_WIDTH/@EntryValue" value="4" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TYPE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_BINARY_OPSIGN/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_ARGUMENTS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_RPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_RPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_TERNARY_OPSIGNS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_PARAMETERS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
<option name="/Default/CodeStyle/EditorConfig/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
</component>
</project>

365
.idea/workspace.xml generated
View File

@@ -1,365 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="BackendCodeEditorMiscSettings">
<option name="/Default/Housekeeping/FeatureSuggestion/FeatureSuggestionManager/DisabledSuggesters/=SwitchToGoToActionSuggester/@EntryIndexedValue" value="true" type="bool" />
</component>
<component name="CMakePresetLoader">{
&quot;useNewFormat&quot;: true
}</component>
<component name="CMakeProjectFlavorService">
<option name="flavorId" value="CMakePlainProjectFlavor" />
</component>
<component name="CMakeReloadState">
<option name="reloaded" value="true" />
</component>
<component name="CMakeRunConfigurationManager">
<generated>
<config projectName="argument_parser" targetName="test" />
</generated>
</component>
<component name="CMakeSettings">
<configurations>
<configuration PROFILE_NAME="Debug" ENABLED="true" CONFIG_NAME="Debug" GENERATION_OPTIONS="-G Ninja -DCMAKE_BUILD_TYPE=Debug" />
<configuration PROFILE_NAME="Release" ENABLED="true" CONFIG_NAME="Release" GENERATION_OPTIONS="-G Ninja -DCMAKE_BUILD_TYPE=Release" />
</configurations>
</component>
<component name="ChangeListManager">
<list default="true" id="7ddada81-7b11-42b9-8fbe-5e1e6cce3b05" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/include/argparse" beforeDir="false" afterPath="$PROJECT_DIR$/include/argparse" afterDir="false" />
<change beforePath="$PROJECT_DIR$/include/parser/platform_headers/macos_parser.hpp" beforeDir="false" afterPath="$PROJECT_DIR$/include/parser/platform_headers/macos_parser.hpp" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="ClangdSettings">
<option name="formatViaClangd" value="false" />
</component>
<component name="ExecutionTargetManager" SELECTED_TARGET="CMakeBuildProfile:Debug" />
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
<option name="RESET_MODE" value="HARD" />
</component>
<component name="HighlightingSettingsPerFile">
<setting file="mock:///Users/killua/Projects/argument-parser/include/argparse" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///Users/killua/Projects/argument-parser/include/parser/argument_parser.hpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///Users/killua/Projects/argument-parser/include/parser/platform_headers/macos_parser.hpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///Users/killua/Projects/argument-parser/src/main.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///dummy.cpp" root0="SKIP_HIGHLIGHTING" />
</component>
<component name="ProjectApplicationVersion">
<option name="ide" value="CLion" />
<option name="majorVersion" value="2025" />
<option name="minorVersion" value="2.3" />
<option name="productBranch" value="Classic" />
</component>
<component name="ProjectColorInfo">{
&quot;associatedIndex&quot;: 5
}</component>
<component name="ProjectId" id="33gk58BoSkVT3osKJJ81IgwdTvK" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
"CMake Application.test.executor": "Debug",
"ModuleVcsDetector.initialDetectionPerformed": "true",
"RunOnceActivity.RadMigrateCodeStyle": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
"RunOnceActivity.cidr.known.project.marker": "true",
"RunOnceActivity.git.unshallow": "true",
"RunOnceActivity.readMode.enableVisualFormatting": "true",
"RunOnceActivity.west.config.association.type.startup.service": "true",
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
"cf.first.check.clang-format": "false",
"cidr.known.project.marker": "true",
"git-widget-placeholder": "main",
"last_opened_file_path": "/Users/killua/Projects/argument-parser",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"settings.editor.selected.configurable": "CMakeSettings",
"vue.rearranger.settings.migration": "true"
}
}]]></component>
<component name="RunManager">
<configuration default="true" type="CLionExternalRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true">
<method v="2">
<option name="CLION.EXTERNAL.BUILD" enabled="true" />
</method>
</configuration>
<configuration name="test" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="-h " REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="argument_parser" TARGET_NAME="test" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="argument_parser" RUN_TARGET_NAME="test">
<method v="2">
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
</method>
</configuration>
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="7ddada81-7b11-42b9-8fbe-5e1e6cce3b05" name="Changes" comment="" />
<created>1759745916574</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1759745916574</updated>
<workItem from="1759745917880" duration="2252000" />
<workItem from="1759749176613" duration="2694000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="VCPKGProject">
<isAutomaticCheckingOnLaunch value="false" />
<isAutomaticFoundErrors value="true" />
<isAutomaticReloadCMake value="true" />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State />
</value>
</entry>
</map>
</option>
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
<breakpoints>
<line-breakpoint enabled="true" type="com.jetbrains.cidr.execution.debugger.OCBreakpointType">
<url>file://$PROJECT_DIR$/include/parser/argument_parser.hpp</url>
<line>145</line>
<option name="timeStamp" value="4" />
</line-breakpoint>
<line-breakpoint enabled="true" type="com.jetbrains.cidr.execution.debugger.OCBreakpointType">
<url>file://$PROJECT_DIR$/include/parser/argument_parser.hpp</url>
<line>277</line>
<option name="timeStamp" value="6" />
</line-breakpoint>
<line-breakpoint enabled="true" type="com.jetbrains.cidr.execution.debugger.OCBreakpointType">
<url>file://$PROJECT_DIR$/include/parser/argument_parser.hpp</url>
<line>276</line>
<option name="timeStamp" value="7" />
</line-breakpoint>
<line-breakpoint enabled="true" type="com.jetbrains.cidr.execution.debugger.OCBreakpointType">
<url>file://$PROJECT_DIR$/include/parser/argument_parser.hpp</url>
<line>219</line>
<option name="timeStamp" value="9" />
</line-breakpoint>
</breakpoints>
</breakpoint-manager>
</component>
</project>

217
README.md
View File

@@ -1,17 +1,21 @@
# argument-parser # argument-parser
A lightweight, modern, expressively typed, and highly customizable C++17 argument parser library. A lightweight, modern, and highly customizable C++17 argument parser with native platform argument collection, trait-driven typed parsing, pluggable option conventions, and a fluent `v2` builder API.
> `v1` is deprecated and mainly kept as implementation history. For new projects, use `argument_parser::v2` together with `argument_parser::builder`.
## Features ## Features
- **Type-safe Argument Extraction**: Use type traits to automatically parse fundamental types and custom structures (e.g. `std::vector<int>`, `std::regex`, `Point`). - Native platform parser alias: `argument_parser::v2::parser` resolves to the current platform parser and reads arguments directly from OS APIs.
- **Support for Multiple Parsing Conventions**: Pluggable convention system out of the box, offering GNU-style (`-a`, `--arg`), GNU-equal-style (`--arg=value`), Windows-style (`/arg`), and Windows-equal-style (`/arg:value`). - Fluent builder API with compile-time builder constraints that prevent invalid combinations after a terminal/mutually exclusive mode has been selected.
- **Automated Help Text Formatting**: Call `parser.display_help(conventions)` to easily generate beautifully formatted usage instructions. - Type-safe parsing and extraction. Just extend `parser_trait<T>` for your types and if just want to store use `get_optional<T>()`!
- **Cross-Platform Native Parsers**: Dedicated parsers that automatically fetch command-line arguments using OS-specific APIs (`windows_parser`, `linux_parser`, `macos_parser`), so you don't need to manually pass `argc` and `argv` on most platforms. - Positional arguments with optional explicit ordering and support for `--` as a positional separator.
- **Fluid setup**: Enjoy fluid setup routines with maps and initializer lists. - Trait-driven `format_hint` and `purpose_hint` metadata used in generated help text and parse errors.
- Automatic help flag on `argument_parser::v2::parser` (`-h`, `--help`) with configurable exit behavior.
### Important Note: - Auto-formatted help output..
V1 is deprecated and is mainly kept as a base implementation for the V2. You should use V2 for your projects. If any features are missing compared to V1, please let me know so I can introduce them! - Completion hooks via `parser.on_complete(...)`.
- Pluggable conventions for GNU next-token, GNU equal-style, Windows next-token, and Windows inline `=` / `:` parsing, or bring your own!
- Testing helper + pseudo command handler `argument_parser::v2::fake_parser`.
## Requirements ## Requirements
@@ -20,104 +24,193 @@ V1 is deprecated and is mainly kept as a base implementation for the V2. You sho
## Quick Start ## Quick Start
### 1. Create your Parser and Define Arguments
```cpp ```cpp
#include <argparse>
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <regex>
#include <argparse> // Provides the native parser for your compiling platform using argument = argument_parser::builder::argument<>;
int main() { int main() {
using namespace argument_parser::v2::flags; argument_parser::v2::parser parser(false); // --help prints without exiting immediately
// Automatically uses the platform-native parser! int threshold = 0;
// It will fetch arguments directly from OS APIs (e.g., GetCommandLineW on Windows)
argument_parser::v2::parser parser;
// A flag with an action argument::start()
parser.add_argument<std::string>({ .short_argument("e")
{ShortArgument, "e"}, .long_argument("echo")
{LongArgument, "echo"}, .action<std::string>([](std::string const& text) {
{Action, argument_parser::helpers::make_parametered_action<std::string>( std::cout << text << '\n';
[](std::string const &text) { std::cout << text << std::endl; } })
)}, .build(parser);
{HelpText, "echoes given variable"}
});
// A flag that just stores the value to extract later argument::start()
parser.add_argument<std::regex>({ .long_argument("file")
{ShortArgument, "g"}, .store<std::string>()
{LongArgument, "grep"}, .required()
{HelpText, "Grep pattern"} .help_text("Input file to process.")
}); .build(parser);
// A required flag argument::start()
parser.add_argument<std::string>({ .long_argument("threshold")
{LongArgument, "file"}, .reference(threshold)
{Required, true}, .build(parser);
{HelpText, "File to grep"}
});
// Run action callback on complete argument::start()
parser.on_complete([](argument_parser::base_parser const &p) { .short_argument("v")
auto filename = p.get_optional<std::string>("file"); .long_argument("verbose")
auto pattern = p.get_optional<std::regex>("grep"); .flag()
.help_text("Enable verbose output.")
.build(parser);
if (filename && pattern) { argument::start()
std::cout << "Grepping " << filename.value() << " with pattern." << std::endl; .positional("output")
.position(0)
.help_text("Output file.")
.build(parser);
parser.on_complete([](auto const& state) {
if (auto file = state.template get_optional<std::string>("file")) {
std::cout << "completed for: " << *file << '\n';
} }
}); });
// Register Conventions
const std::initializer_list<argument_parser::conventions::convention const *const> conventions = { const std::initializer_list<argument_parser::conventions::convention const *const> conventions = {
&argument_parser::conventions::gnu_argument_convention, &argument_parser::conventions::gnu_argument_convention,
&argument_parser::conventions::windows_argument_convention &argument_parser::conventions::gnu_equal_argument_convention,
&argument_parser::conventions::windows_argument_convention,
&argument_parser::conventions::windows_equal_argument_convention,
}; };
// Execute logic!
parser.handle_arguments(conventions); parser.handle_arguments(conventions);
return 0; if (auto file = parser.get_optional<std::string>("file")) {
std::cout << "file: " << *file << '\n';
}
std::cout << "threshold: " << threshold << '\n';
} }
``` ```
### 2. Custom Type Parsing ## Trait-Driven Parsing and Hints
You can natively parse your custom structs, objects, or arrays by specializing `argument_parser::parsing_traits::parser_trait<T>`. Specialize `argument_parser::parsing_traits::parser_trait<T>` to add support for your own types and to describe their expected format.
```cpp ```cpp
#include <macros.h>
#include <traits.hpp>
#include <stdexcept>
#include <string>
struct Point { struct Point {
int x, y; int x;
int y;
}; };
template <> struct argument_parser::parsing_traits::parser_trait<Point> { template <>
static Point parse(const std::string &input) { struct argument_parser::parsing_traits::parser_trait<Point> {
auto comma_pos = input.find(','); static Point parse(std::string const& input) {
int x = std::stoi(input.substr(0, comma_pos)); auto comma = input.find(',');
int y = std::stoi(input.substr(comma_pos + 1)); if (comma == std::string::npos) {
return {x, y}; throw std::runtime_error("Expected x,y");
} }
};
// Now you can directly use your type: return {
// parser.add_argument<Point>({ {LongArgument, "point"} }); std::stoi(input.substr(0, comma)),
// auto point = parser.get_optional<Point>("point"); std::stoi(input.substr(comma + 1))
};
}
ARGPARSE_TRAIT_FORMAT_HINT = "x,y";
ARGPARSE_TRAIT_PURPOSE_HINT = "point coordinates";
};
```
Then use the type directly from the builder:
```cpp
argument::start()
.long_argument("point")
.store<Point>()
.build(parser);
```
If you omit `help_text()`, `v2` uses the trait hints to generate help such as `Accepts point coordinates in x,y format.` The same hints are also included in type conversion errors.
## Help Behavior
`argument_parser::v2::parser` automatically registers `-h` and `--help`.
```cpp
argument_parser::v2::parser parser; // help prints and exits
argument_parser::v2::parser parser(false); // help prints without immediate exit
```
You can also display help manually:
```cpp
parser.display_help(conventions);
```
## Supported Conventions
- GNU next-token: `-o value`, `--output value`
- GNU equal-style: `-o=value`, `--output=value`
- Windows next-token: `/output value`
- Windows inline value: `/output=value`, `/output:value`
Mix any of them in the same parser by passing the conventions you want to `handle_arguments()`.
## Builder Modes
`argument_parser::builder::argument<>` is a staged builder. `build(parser)` is the terminal call.
Before `build(...)`, you compose an argument from three kinds of steps:
- Identifier selection: `short_argument(...)`, `long_argument(...)`, or `positional(...)`
- Optional metadata: `position(...)` for positional arguments, `help_text(...)`, and `required(...)`
- One mutually exclusive value behavior:
- `store<T>()` to parse and retain a value for later `get_optional<T>()`
- `flag()` to store a boolean presence flag
- `reference(value)` to write the parsed result directly into an existing variable
- `action([] { ... })` for no-value callbacks
- `action<T>([](T const&) { ... })` for typed value callbacks
Once you select one value behavior, the other value behavior methods are disabled at compile time, so combinations like `store<T>().action(...)` or `flag().reference(value)` are rejected by the type system. Also you cannot use the same method repeatedly as it is also disabled at compile time by the type system.
If you do not select a value behavior explicitly, `build(parser)` uses the default for the argument kind: named arguments become boolean flags, while positional arguments store a `std::string`.
## Testing
For unit tests or synthetic argument lists, use `argument_parser::v2::fake_parser` instead of the native platform parser:
```cpp
#include <fake_parser.hpp>
argument_parser::v2::fake_parser parser("tool", {"--count", "3", "input.txt"});
``` ```
## CMake Integration ## CMake Integration
The library can be installed globally via CMake or incorporated into your project. Use the project directly:
```cmake ```cmake
add_subdirectory(argument-parser) add_subdirectory(argument-parser)
target_link_libraries(your_target PRIVATE argument_parser) target_link_libraries(your_target PRIVATE argument_parser)
``` ```
Or install and consume it as a package:
```cmake
find_package(argument_parser CONFIG REQUIRED)
target_link_libraries(your_target PRIVATE argument_parser::argument_parser)
```
## Building & Installing ## Building & Installing
```bash ```bash
mkdir build && cd build mkdir build && cd build
cmake .. cmake ..
cmake --build . cmake --build .
cmake --install .
``` ```

32
TODO.md
View File

@@ -46,12 +46,38 @@ instead of an action doing it.
# TODO 7: Defaults/Implicits # TODO 7: Defaults/Implicits
If given, an arguments default store value could be changed. If nothing was given use that value instead. If given, an arguments default store value could be changed. If nothing was given use that value instead.
# TODO 8: Validators # TODO 8: Validators | DONE
If given, validate the argument before passing to the storage or action. If fail, let user decide fail loud or fail skip. If given, validate the argument before passing to the storage or action. If fail, let user decide fail loud or fail skip.
# TODO 9: Subcommand/Subactions # TODO 9: Subcommand/Subactions
Implement subcommand support. Users should be able to define subactions to the higher level action. For example, Implement subcommand support. Users should be able to define subactions to the higher level action. For example,
```cpp ```cpp
parser.add_argument<std::string>( parser.add_argument(
{{ShortArgument, "l"}, {LongArgument, "list"}, {Action, list_files}, {HelpText, "Lists files in the directory"}}); {{ShortArgument, "g"}, {LongArgument, "get"}, {Action, get_}, {HelpText, "Gets <files, system_info, status>"}}
);
parser.add_argument(
{{BaseArgument, "g"}, {ShortArgument, "f"}, {LongArgument, "files"}, {Action, get_files}, {HelpText, "Gets files"}}
);
...
```
# TODO 10: Reference capture | DONE
Reference capturing.
```cpp
parser.add_argument<int>({
{ShortArgument, "c"},
{HelpText, "capture value"},
{Reference, &captured_value},
});
```
# TODO 11: Builder | DONE
Implement type safe logic enforcing argument builder;
```cpp
argument::start()
.short_argument("e")
.long_argument("echo")
.help_text("Echo the parsed value.")
.action(echo)
.build(parser);
``` ```

View File

@@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 3.10)
project(test)
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
find_package(argument_parser REQUIRED)
add_executable(main main.cpp)
target_link_libraries(main argument_parser)

104
examples/test/main.cpp Normal file
View File

@@ -0,0 +1,104 @@
#include <argparse>
#include <gnu_argument_convention.hpp>
#include <iostream>
#include <macros.h>
#include <parser_v2.hpp>
#include <string>
#include <traits.hpp>
using argument = argument_parser::builder::argument<>;
using argument_parser::parsing_traits::hint_type;
auto echo(std::string const &s) -> void {
std::cout << s << '\n';
}
using namespace argument_parser::parsing_traits;
constexpr hint_type vector_purpose_hint = "vector of ";
template <typename T> class parser_trait<std::vector<T>> {
public:
static std::vector<T> parse(std::string const &s) {
std::vector<T> result;
std::stringstream ss(s);
for (std::string line; std::getline(ss, line, ',');) {
T item = parser_trait<T>::parse(line);
result.push_back(item);
}
return result;
}
ARGPARSE_TRAIT_FORMAT_HINT = concat<hint_provider<&parser_trait<T>::format_hint>, hint_provider<&comma>,
hint_provider<&parser_trait<T>::format_hint>>;
ARGPARSE_TRAIT_PURPOSE_HINT =
concat<hint_provider<&vector_purpose_hint>, hint_provider<&parser_trait<T>::purpose_hint>>;
};
using namespace argument_parser::v2::flags;
auto main() -> int {
argument_parser::v2::parser parser(false);
argument::start()
.positional("count")
.position(1)
.help_text("How many times to repeat the action.")
.action<int>([](int const &count) { std::cout << "count action configured for " << count << '\n'; })
.build(parser);
int captured_value = 0;
argument::start()
.long_argument("threshold")
.help_text("Store the parsed value through a reference.")
.reference(captured_value)
.build(parser);
argument::start()
.positional("captured")
.position(0)
.help_text("Store the parsed value through a reference.")
.reference(captured_value)
.build(parser);
// parser.add_argument<int>({
// {ShortArgument, "c"},
// {HelpText, "capture count"},
// {Reference, &captured_value},
// });
argument::start().short_argument("q").help_text("Store a boolean flag.").build(parser);
// argument::start()
// .long_argument("regex")
// .help_text("Store a regex value.")
// .store<std::optional<std::regex>>()
// .build(parser);
argument::start()
.short_argument("e")
.long_argument("echo")
.help_text("Echo the parsed value.")
.action(echo)
.build(parser);
argument::start()
.long_argument("vecstr")
.short_argument("vs")
.action<std::vector<int>>([](std::vector<int> const &vecstr) {
for (auto const &str : vecstr) {
std::cout << str << '\n';
}
})
.build(parser);
parser.handle_arguments({&argument_parser::conventions::gnu_argument_convention});
std::cout << "captured value: " << captured_value << '\n';
return 0;
}

View File

@@ -1,8 +1,10 @@
#pragma once #pragma once
#ifndef ARGPARSE_HPP #ifndef ARGPARSE_HPP
#define ARGPARSE_HPP #define ARGPARSE_HPP
#include <argument_parser.hpp>
#include "macros.h" #include "macros.h"
#include <argument_builder.hpp>
#include <argument_parser.hpp>
#include <parser_v2.hpp>
#ifdef __linux__ #ifdef __linux__
#include <linux_parser.hpp> #include <linux_parser.hpp>

View File

@@ -20,8 +20,8 @@ namespace argument_parser::conventions {
virtual std::string name() const = 0; virtual std::string name() const = 0;
virtual std::string short_prec() const = 0; virtual std::string short_prec() const = 0;
virtual std::string long_prec() const = 0; virtual std::string long_prec() const = 0;
virtual std::pair<std::string, std::string> make_help_text(std::string const &short_arg, std::string const &long_arg, virtual std::pair<std::string, std::string>
bool requires_value) const = 0; make_help_text(std::string const &short_arg, std::string const &long_arg, bool requires_value) const = 0;
virtual std::vector<convention_features> get_features() const = 0; virtual std::vector<convention_features> get_features() const = 0;
protected: protected:

View File

@@ -0,0 +1,510 @@
#pragma once
#include "argument_parser.hpp"
#include <functional>
#include <parser_v2.hpp>
#include <type_traits>
#ifndef ARGUMENT_PARSER_PARSER_V3_HPP
#define ARGUMENT_PARSER_PARSER_V3_HPP
namespace argument_parser::builder {
class non_type {};
namespace builder_mask {
using v2_flag = argument_parser::v2::add_argument_flags;
using mask_type = std::uint64_t;
enum class value_mode { unresolved, store, flag, reference, nonparametered_action, parametered_action };
enum class extra_capability : unsigned { Store = static_cast<unsigned>(v2_flag::Reference) + 1, Flag };
constexpr auto bit(v2_flag flag) -> mask_type {
return mask_type{1} << static_cast<unsigned>(flag);
}
constexpr auto bit(extra_capability capability) -> mask_type {
return mask_type{1} << static_cast<unsigned>(capability);
}
constexpr mask_type short_argument = bit(v2_flag::ShortArgument);
constexpr mask_type long_argument = bit(v2_flag::LongArgument);
constexpr mask_type positional = bit(v2_flag::Positional);
constexpr mask_type position = bit(v2_flag::Position);
constexpr mask_type help_text = bit(v2_flag::HelpText);
constexpr mask_type action = bit(v2_flag::Action);
constexpr mask_type required = bit(v2_flag::Required);
constexpr mask_type reference = bit(v2_flag::Reference);
constexpr mask_type store = bit(extra_capability::Store);
constexpr mask_type flag = bit(extra_capability::Flag);
constexpr mask_type value_mode_group = action | reference | store | flag;
constexpr mask_type initial =
short_argument | long_argument | positional | help_text | action | required | reference | store | flag;
constexpr auto has(mask_type mask, mask_type capability) -> bool {
return (mask & capability) == capability;
}
constexpr auto remove(mask_type mask, mask_type capability) -> mask_type {
return mask & ~capability;
}
constexpr auto replace(mask_type mask, mask_type remove_bits, mask_type add_bits = 0) -> mask_type {
return (mask & ~remove_bits) | add_bits;
}
constexpr auto has_selected_identifier(mask_type mask) -> bool {
return !has(mask, short_argument) || !has(mask, long_argument) || !has(mask, positional);
}
constexpr auto is_buildable(mask_type mask) -> bool {
return has_selected_identifier(mask);
}
} // namespace builder_mask
template <builder_mask::mask_type mask = builder_mask::initial, typename store_type = non_type> class argument {
public:
using mask_type = builder_mask::mask_type;
using v2_flag = argument_parser::v2::add_argument_flags;
using value_mode = builder_mask::value_mode;
static auto start() -> argument<builder_mask::initial> {
return {};
}
template <mask_type current_mask = mask,
std::enable_if_t<builder_mask::has(current_mask, builder_mask::short_argument), int> = 0>
auto short_argument(std::string short_name) const
-> argument<builder_mask::replace(current_mask, builder_mask::short_argument | builder_mask::positional |
builder_mask::position),
store_type> {
using next_argument =
argument<builder_mask::replace(current_mask, builder_mask::short_argument | builder_mask::positional |
builder_mask::position),
store_type>;
next_argument next{*this};
next.m_short_argument = std::move(short_name);
return next;
}
template <mask_type current_mask = mask,
std::enable_if_t<builder_mask::has(current_mask, builder_mask::long_argument), int> = 0>
auto long_argument(std::string long_name) const
-> argument<builder_mask::replace(current_mask, builder_mask::long_argument | builder_mask::positional |
builder_mask::position),
store_type> {
using next_argument =
argument<builder_mask::replace(current_mask, builder_mask::long_argument | builder_mask::positional |
builder_mask::position),
store_type>;
next_argument next{*this};
next.m_long_argument = std::move(long_name);
return next;
}
template <mask_type current_mask = mask,
std::enable_if_t<builder_mask::has(current_mask, builder_mask::positional), int> = 0>
auto positional(std::string positional_name) const
-> argument<builder_mask::replace(current_mask,
builder_mask::short_argument | builder_mask::long_argument |
builder_mask::positional | builder_mask::flag,
builder_mask::position),
store_type> {
using next_argument =
argument<builder_mask::replace(current_mask,
builder_mask::short_argument | builder_mask::long_argument |
builder_mask::positional | builder_mask::flag,
builder_mask::position),
store_type>;
next_argument next{*this};
next.m_positional_name = std::move(positional_name);
return next;
}
template <mask_type current_mask = mask,
std::enable_if_t<builder_mask::has(current_mask, builder_mask::position), int> = 0>
auto position(int index) const
-> argument<builder_mask::remove(current_mask, builder_mask::position), store_type> {
using next_argument = argument<builder_mask::remove(current_mask, builder_mask::position), store_type>;
next_argument next{*this};
next.m_position = index;
return next;
}
template <mask_type current_mask = mask,
std::enable_if_t<builder_mask::has(current_mask, builder_mask::help_text), int> = 0>
auto help_text(std::string help) const
-> argument<builder_mask::remove(current_mask, builder_mask::help_text), store_type> {
using next_argument = argument<builder_mask::remove(current_mask, builder_mask::help_text), store_type>;
next_argument next{*this};
next.m_help_text = std::move(help);
return next;
}
template <mask_type current_mask = mask,
std::enable_if_t<builder_mask::has(current_mask, builder_mask::required), int> = 0>
auto required(bool value = true) const
-> argument<builder_mask::remove(current_mask, builder_mask::required), store_type> {
using next_argument = argument<builder_mask::remove(current_mask, builder_mask::required), store_type>;
next_argument next{*this};
next.m_required = value;
return next;
}
template <typename T = std::string, mask_type current_mask = mask,
std::enable_if_t<builder_mask::has(current_mask, builder_mask::store), int> = 0>
auto store() const -> argument<builder_mask::remove(current_mask, builder_mask::value_mode_group), T> {
static_assert(!std::is_same_v<T, void>,
"store<void>() is not supported. Use flag() for boolean-style arguments.");
using next_argument = argument<builder_mask::remove(current_mask, builder_mask::value_mode_group), T>;
next_argument next{*this};
next.m_value_mode = value_mode::store;
return next;
}
template <mask_type current_mask = mask,
std::enable_if_t<builder_mask::has(current_mask, builder_mask::flag), int> = 0>
auto flag() const -> argument<builder_mask::remove(current_mask, builder_mask::value_mode_group), bool> {
using next_argument = argument<builder_mask::remove(current_mask, builder_mask::value_mode_group), bool>;
next_argument next{*this};
next.m_value_mode = value_mode::flag;
return next;
}
template <mask_type current_mask = mask,
std::enable_if_t<builder_mask::has(current_mask, builder_mask::reference), int> = 0, typename T>
auto reference(T &value) const
-> argument<builder_mask::remove(current_mask, builder_mask::value_mode_group), T> {
using next_argument = argument<builder_mask::remove(current_mask, builder_mask::value_mode_group), T>;
next_argument next{*this};
next.m_reference = std::addressof(value);
next.m_value_mode = value_mode::reference;
return next;
}
template <mask_type current_mask = mask,
std::enable_if_t<builder_mask::has(current_mask, builder_mask::action), int> = 0, typename Callable>
auto action(Callable &&handler) const -> std::enable_if_t<
std::is_invocable_r_v<void, Callable>,
argument<builder_mask::remove(current_mask, builder_mask::value_mode_group), non_type>> {
using next_argument =
argument<builder_mask::remove(current_mask, builder_mask::value_mode_group), non_type>;
next_argument next{*this};
next.m_action = std::make_shared<argument_parser::non_parametered_action>(
std::function<void()>(std::forward<Callable>(handler)));
next.m_value_mode = value_mode::nonparametered_action;
return next;
}
template <typename T = std::string, mask_type current_mask = mask,
std::enable_if_t<builder_mask::has(current_mask, builder_mask::action), int> = 0, typename Callable>
auto action(Callable &&handler) const
-> std::enable_if_t<std::is_invocable_r_v<void, Callable, const T &>,
argument<builder_mask::remove(current_mask, builder_mask::value_mode_group), T>> {
static_assert(!std::is_same_v<T, void>,
"action<void>(...) is not supported. Use action([] { ... }) instead.");
using next_argument = argument<builder_mask::remove(current_mask, builder_mask::value_mode_group), T>;
next_argument next{*this};
next.m_action = std::make_shared<argument_parser::parametered_action<T>>(
std::function<void(const T &)>(std::forward<Callable>(handler)));
next.m_value_mode = value_mode::parametered_action;
return next;
}
template <mask_type current_mask = mask, std::enable_if_t<builder_mask::is_buildable(current_mask), int> = 0>
auto build(argument_parser::v2::base_parser &parser) const -> void {
assert_has_identifier();
switch (m_value_mode) {
case value_mode::flag:
build_flag(parser);
return;
case value_mode::nonparametered_action:
build_nonparametered_action(parser);
return;
case value_mode::store:
if constexpr (!std::is_same_v<store_type, non_type>) {
build_store(parser);
return;
}
break;
case value_mode::reference:
if constexpr (!std::is_same_v<store_type, non_type>) {
build_reference(parser);
return;
}
break;
case value_mode::parametered_action:
if constexpr (!std::is_same_v<store_type, non_type>) {
build_parametered_action(parser);
return;
}
break;
case value_mode::unresolved:
if (is_positional()) {
build_default_positional(parser);
} else {
build_flag(parser);
}
return;
}
throw std::logic_error("The builder reached build() without a supported terminal value mode.");
}
private:
argument() = default;
template <mask_type other_mask, typename other_store_type>
argument(argument<other_mask, other_store_type> const &other)
: m_short_argument(other.m_short_argument), m_long_argument(other.m_long_argument),
m_positional_name(other.m_positional_name), m_position(other.m_position), m_help_text(other.m_help_text),
m_required(other.m_required), m_action(other.m_action), m_reference(copy_reference(other.m_reference)),
m_value_mode(other.m_value_mode) {}
template <typename T>
using typed_map =
std::unordered_map<v2_flag, typename argument_parser::v2::base_parser::template typed_flag_value<T>>;
using non_typed_map = std::unordered_map<v2_flag, argument_parser::v2::base_parser::non_typed_flag_value>;
auto is_positional() const -> bool {
return !m_positional_name.empty();
}
auto lookup_key() const -> std::string {
if (is_positional()) {
return m_positional_name;
}
if (!m_long_argument.empty()) {
return m_long_argument;
}
if (!m_short_argument.empty()) {
return m_short_argument;
}
throw std::logic_error("No argument identifier is available for lookup.");
}
auto assert_has_identifier() const -> void {
if (!is_positional() && m_short_argument.empty() && m_long_argument.empty()) {
throw std::logic_error("build() requires short_argument(), long_argument(), or positional().");
}
}
template <typename Map> auto add_common_pairs(Map &pairs) const -> void {
using namespace argument_parser::v2::flags;
if (is_positional()) {
pairs[Positional] = m_positional_name;
if (m_position.has_value()) {
pairs[Position] = m_position.value();
}
} else {
if (!m_short_argument.empty()) {
pairs[ShortArgument] = m_short_argument;
}
if (!m_long_argument.empty()) {
pairs[LongArgument] = m_long_argument;
}
}
if (!m_help_text.empty()) {
pairs[HelpText] = m_help_text;
}
if (m_required) {
pairs[Required] = true;
}
}
template <typename T> auto make_typed_pairs() const -> typed_map<T> {
typed_map<T> pairs;
add_common_pairs(pairs);
return pairs;
}
auto make_non_typed_pairs() const -> non_typed_map {
non_typed_map pairs;
add_common_pairs(pairs);
return pairs;
}
auto build_flag(argument_parser::v2::base_parser &parser) const -> void {
auto pairs = make_non_typed_pairs();
parser.add_argument(pairs);
}
auto build_default_positional(argument_parser::v2::base_parser &parser) const -> void {
auto pairs = make_non_typed_pairs();
parser.add_argument(pairs);
}
auto build_store(argument_parser::v2::base_parser &parser) const -> void {
auto pairs = make_typed_pairs<store_type>();
parser.template add_argument<store_type>(pairs);
}
auto build_reference(argument_parser::v2::base_parser &parser) const -> void {
auto pairs = make_typed_pairs<store_type>();
auto *target = m_reference;
auto key = lookup_key();
if (target == nullptr) {
throw std::logic_error("reference() was selected without a target.");
}
pairs[argument_parser::v2::flags::Reference] = target;
parser.template add_argument<store_type>(pairs);
}
auto build_parametered_action(argument_parser::v2::base_parser &parser) const -> void {
auto const *typed_action =
dynamic_cast<argument_parser::parametered_action<store_type> const *>(m_action.get());
if (typed_action == nullptr) {
throw std::logic_error("Stored action is not compatible with the requested parameter type.");
}
auto pairs = make_typed_pairs<store_type>();
pairs[argument_parser::v2::flags::Action] = *typed_action;
parser.template add_argument<store_type>(pairs);
}
auto build_nonparametered_action(argument_parser::v2::base_parser &parser) const -> void {
auto const *nonparametered_action =
dynamic_cast<argument_parser::non_parametered_action const *>(m_action.get());
if (nonparametered_action == nullptr) {
throw std::logic_error("Stored action is not a non-parametered action.");
}
if (is_positional()) {
auto wrapped_action = argument_parser::helpers::make_parametered_action<std::string>(
[action = *nonparametered_action](std::string const &) { action.invoke(); });
auto pairs = make_typed_pairs<std::string>();
pairs[argument_parser::v2::flags::Action] = wrapped_action;
parser.template add_argument<std::string>(pairs);
return;
}
auto pairs = make_non_typed_pairs();
pairs[argument_parser::v2::flags::Action] = *nonparametered_action;
parser.add_argument(pairs);
}
std::string m_short_argument{};
std::string m_long_argument{};
std::string m_positional_name{};
std::optional<int> m_position{};
std::string m_help_text{};
bool m_required = false;
std::shared_ptr<argument_parser::action_base const> m_action{};
store_type *m_reference = nullptr;
value_mode m_value_mode = value_mode::unresolved;
template <typename other_store_type> static auto copy_reference(other_store_type *reference) -> store_type * {
if constexpr (std::is_same_v<store_type, other_store_type>) {
return reference;
} else {
return nullptr;
}
}
template <mask_type other_mask, typename other_store_type> friend class argument;
};
namespace assertions {
struct noop_handler {
void operator()() const {}
};
template <typename T> struct parameter_sink {
void operator()(T const &) const {}
};
template <typename T, typename = void> struct can_use_help_text : std::false_type {};
template <typename T>
struct can_use_help_text<T, std::void_t<decltype(std::declval<T>().help_text(std::declval<std::string>()))>>
: std::true_type {};
template <typename T, typename = void> struct can_use_position : std::false_type {};
template <typename T>
struct can_use_position<T, std::void_t<decltype(std::declval<T>().position(0))>> : std::true_type {};
template <typename T, typename = void> struct can_use_nonparametered_action : std::false_type {};
template <typename T>
struct can_use_nonparametered_action<T, std::void_t<decltype(std::declval<T>().action(noop_handler{}))>>
: std::true_type {};
template <typename T, typename U, typename = void> struct can_use_parametered_action : std::false_type {};
template <typename T, typename U>
struct can_use_parametered_action<
T, U, std::void_t<decltype(std::declval<T>().template action<U>(parameter_sink<U>{}))>> : std::true_type {};
template <typename T, typename U, typename = void> struct can_use_store : std::false_type {};
template <typename T, typename U>
struct can_use_store<T, U, std::void_t<decltype(std::declval<T>().template store<U>())>> : std::true_type {};
template <typename T, typename = void> struct can_use_flag : std::false_type {};
template <typename T>
struct can_use_flag<T, std::void_t<decltype(std::declval<T>().flag())>> : std::true_type {};
template <typename T, typename U, typename = void> struct can_use_reference : std::false_type {};
template <typename T, typename U>
struct can_use_reference<T, U, std::void_t<decltype(std::declval<T>().reference(std::declval<U &>()))>>
: std::true_type {};
using after_help_text = decltype(argument<>::start().help_text("help"));
static_assert(!can_use_help_text<after_help_text>::value, "help_text() should be single-use.");
using after_positional = decltype(argument<>::start().positional("path"));
static_assert(can_use_position<after_positional>::value, "positional() should unlock position().");
using after_position = decltype(argument<>::start().positional("path").position(0));
static_assert(!can_use_position<after_position>::value, "position() should be single-use.");
using after_positional_mode_selection = decltype(argument<>::start().positional("path").store<>());
static_assert(!can_use_flag<after_positional_mode_selection>::value,
"flag() should not be available for positional arguments.");
using after_nonparametered_action =
decltype(argument<>::start().short_argument("v").help_text("verbose").action(noop_handler{}));
static_assert(!can_use_nonparametered_action<after_nonparametered_action>::value,
"action() should not remain callable after selecting a non-parametered action.");
static_assert(!can_use_parametered_action<after_nonparametered_action, int>::value,
"typed action() should also be disabled after selecting a non-parametered action.");
static_assert(!can_use_store<after_nonparametered_action, int>::value,
"store() should be mutually exclusive with action().");
static_assert(!can_use_flag<after_nonparametered_action>::value,
"flag() should be mutually exclusive with action().");
static_assert(!can_use_reference<after_nonparametered_action, int>::value,
"reference() should be mutually exclusive with action().");
using after_parametered_action =
decltype(argument<>::start().positional("count").position(0).action<int>(parameter_sink<int>{}));
static_assert(!can_use_nonparametered_action<after_parametered_action>::value,
"non-parametered action() should be disabled after selecting a typed action.");
static_assert(!can_use_parametered_action<after_parametered_action, std::string>::value,
"typed action() should be single-use regardless of the parameter type.");
} // namespace assertions
} // namespace argument_parser::builder
#endif

View File

@@ -31,7 +31,7 @@ namespace argument_parser {
void set_program_name(std::string const &program_name); void set_program_name(std::string const &program_name);
void set_parsed_arguments(std::vector<std::string> const &parsed_arguments); void set_parsed_arguments(std::vector<std::string> const &parsed_arguments);
}; };
} } // namespace v2
} // namespace argument_parser } // namespace argument_parser
#endif #endif

View File

@@ -9,12 +9,22 @@
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <type_traits>
#include <unordered_map> #include <unordered_map>
#include <variant> #include <variant>
#include <vector> #include <vector>
namespace argument_parser::v2 { namespace argument_parser::v2 {
enum class add_argument_flags { ShortArgument, LongArgument, Positional, Position, HelpText, Action, Required }; enum class add_argument_flags {
ShortArgument,
LongArgument,
Positional,
Position,
HelpText,
Action,
Required,
Reference
};
namespace flags { namespace flags {
constexpr static inline add_argument_flags ShortArgument = add_argument_flags::ShortArgument; constexpr static inline add_argument_flags ShortArgument = add_argument_flags::ShortArgument;
@@ -24,11 +34,12 @@ namespace argument_parser::v2 {
constexpr static inline add_argument_flags Required = add_argument_flags::Required; constexpr static inline add_argument_flags Required = add_argument_flags::Required;
constexpr static inline add_argument_flags Positional = add_argument_flags::Positional; constexpr static inline add_argument_flags Positional = add_argument_flags::Positional;
constexpr static inline add_argument_flags Position = add_argument_flags::Position; constexpr static inline add_argument_flags Position = add_argument_flags::Position;
constexpr static inline add_argument_flags Reference = add_argument_flags::Reference;
} // namespace flags } // namespace flags
class base_parser : private argument_parser::base_parser { class base_parser : private argument_parser::base_parser {
public: public:
template <typename T> using typed_flag_value = std::variant<std::string, parametered_action<T>, bool, int>; template <typename T> using typed_flag_value = std::variant<std::string, parametered_action<T>, bool, int, T *>;
using non_typed_flag_value = std::variant<std::string, non_parametered_action, bool, int>; using non_typed_flag_value = std::variant<std::string, non_parametered_action, bool, int>;
template <typename T> using typed_argument_pair = std::pair<add_argument_flags, typed_flag_value<T>>; template <typename T> using typed_argument_pair = std::pair<add_argument_flags, typed_flag_value<T>>;
@@ -144,6 +155,24 @@ namespace argument_parser::v2 {
required = true; required = true;
} }
if (argument_pairs.find(add_argument_flags::Reference) != argument_pairs.end()) {
if (!IsTyped) {
throw std::logic_error("Reference argument must be typed");
}
found_params[extended_add_argument_flags::Action] = true;
if constexpr (!std::is_same_v<T, void>) {
auto ref = get_or_throw<T *>(argument_pairs.at(add_argument_flags::Reference), "reference");
if (action) {
throw std::logic_error("Cannot use both action and reference for the same argument");
} else {
action = helpers::make_parametered_action<T>([ref](T const &t) { *ref = t; }).clone();
}
} else {
throw std::logic_error("Reference argument must not be void");
}
}
auto suggested_add = suggest_candidate(found_params); auto suggested_add = suggest_candidate(found_params);
if (suggested_add == candidate_type::unknown) { if (suggested_add == candidate_type::unknown) {
throw std::runtime_error("Could not match any add argument overload to given parameters. Are you " throw std::runtime_error("Could not match any add argument overload to given parameters. Are you "
@@ -238,6 +267,23 @@ namespace argument_parser::v2 {
position = get_or_throw<int>(argument_pairs.at(add_argument_flags::Position), "position"); position = get_or_throw<int>(argument_pairs.at(add_argument_flags::Position), "position");
} }
if (argument_pairs.find(add_argument_flags::Reference) != argument_pairs.end()) {
if (!IsTyped) {
throw std::logic_error("Reference argument must be typed");
}
if constexpr (!std::is_same_v<T, void>) {
auto ref = get_or_throw<T *>(argument_pairs.at(add_argument_flags::Reference), "reference");
if (action) {
throw std::logic_error("Cannot use both action and reference for the same argument");
} else {
action = helpers::make_parametered_action<T>([ref](T const &t) { *ref = t; }).clone();
}
} else {
throw std::logic_error("Reference argument must not be void");
}
}
if (help_text.empty()) { if (help_text.empty()) {
if constexpr (IsTyped) { if constexpr (IsTyped) {
if constexpr (internal::sfinae::has_format_hint<parsing_traits::parser_trait<T>>::value && if constexpr (internal::sfinae::has_format_hint<parsing_traits::parser_trait<T>>::value &&
@@ -256,8 +302,8 @@ namespace argument_parser::v2 {
if constexpr (IsTyped) { if constexpr (IsTyped) {
if (action) { if (action) {
base::add_positional_argument<T>(positional_name, help_text, base::add_positional_argument<T>(positional_name, help_text, *static_cast<ActionType *>(&(*action)),
*static_cast<ActionType *>(&(*action)), required, position); required, position);
} else { } else {
base::template add_positional_argument<T>(positional_name, help_text, required, position); base::template add_positional_argument<T>(positional_name, help_text, required, position);
} }

View File

@@ -50,6 +50,38 @@ namespace argument_parser::parsing_traits {
static constexpr hint_type format_hint = "3.14"; static constexpr hint_type format_hint = "3.14";
static constexpr hint_type purpose_hint = "double precision floating point number"; static constexpr hint_type purpose_hint = "double precision floating point number";
}; };
constexpr hint_type comma = ",";
template <const hint_type *PtrAddr> struct hint_provider {
static constexpr hint_type value = *PtrAddr;
};
template <typename... Providers> struct joiner {
static constexpr auto get_combined() {
constexpr size_t total_len = (std::string_view{Providers::value}.length() + ... + 0);
std::array<char, total_len + 1> arr{};
size_t offset = 0;
auto append = [&](hint_type s) {
std::string_view sv{s};
for (char c : sv)
arr[offset++] = c;
return 0;
};
(append(Providers::value), ...);
arr[total_len] = '\0';
return arr;
}
static constexpr auto storage = get_combined();
static constexpr hint_type value = storage.data();
};
template <typename... Providers> constexpr hint_type concat = joiner<Providers...>::value;
} // namespace argument_parser::parsing_traits } // namespace argument_parser::parsing_traits
#endif #endif

View File

@@ -1,254 +0,0 @@
#include "macros.h"
#include "traits.hpp"
#include <exception>
#include <memory>
#include <string>
#include <argparse>
#include <fstream>
#include <iostream>
#include <regex>
#include <sstream>
#include <vector>
struct Point {
int x, y;
};
template <> struct argument_parser::parsing_traits::parser_trait<Point> {
static Point parse(const std::string &input) {
auto comma_pos = input.find(',');
if (comma_pos == std::string::npos) {
throw std::runtime_error("Invalid Point format. Expected 'x,y'.");
}
int x = std::stoi(input.substr(0, comma_pos));
int y = std::stoi(input.substr(comma_pos + 1));
return {x, y};
}
static bool validate(Point const& p) {
return p.x >= 0 && p.y >= 0;
}
ARGPARSE_TRAIT_FORMAT_HINT = "x,y";
ARGPARSE_TRAIT_PURPOSE_HINT = "coordinates";
};
template <> struct argument_parser::parsing_traits::parser_trait<std::regex> {
static std::regex parse(const std::string &input) {
return std::regex(input);
}
ARGPARSE_TRAIT_FORMAT_HINT = "regex";
ARGPARSE_TRAIT_PURPOSE_HINT = "regular expression";
};
template <> struct argument_parser::parsing_traits::parser_trait<std::vector<std::string>> {
static std::vector<std::string> parse(const std::string &input) {
std::vector<std::string> result;
std::stringstream ss{input};
std::string item;
while (std::getline(ss, item, ',')) {
result.push_back(item);
}
return result;
}
ARGPARSE_TRAIT_FORMAT_HINT = "string,string,string";
ARGPARSE_TRAIT_PURPOSE_HINT = "list of strings";
};
template <typename VT> struct argument_parser::parsing_traits::parser_trait<std::vector<VT>> {
static std::vector<VT> parse(const std::string &input) {
std::vector<VT> result;
std::stringstream ss{input};
std::string item;
while (std::getline(ss, item, ',')) {
result.push_back(argument_parser::parsing_traits::parser_trait<VT>::parse(item));
}
return result;
}
ARGPARSE_TRAIT_FORMAT_HINT = "VT,VT,VT";
ARGPARSE_TRAIT_PURPOSE_HINT = "list of VT";
};
const std::initializer_list<argument_parser::conventions::convention const *const> conventions = {
&argument_parser::conventions::gnu_argument_convention,
&argument_parser::conventions::gnu_equal_argument_convention,
// &argument_parser::conventions::windows_argument_convention,
// &argument_parser::conventions::windows_equal_argument_convention
};
const auto echo = argument_parser::helpers::make_parametered_action<std::string>(
[](std::string const &text) { std::cout << text << std::endl; });
const auto echo_point = argument_parser::helpers::make_parametered_action<Point>(
[](Point const &point) { std::cout << "Point(" << point.x << ", " << point.y << ")" << std::endl; });
const auto cat = argument_parser::helpers::make_parametered_action<std::string>([](std::string const &file_name) {
std::ifstream file(file_name);
if (!file.is_open()) {
throw std::runtime_error("Could not open file");
}
std::string line;
while (std::getline(file, line)) {
std::cout << line << std::endl;
}
file.close();
});
auto grep(argument_parser::base_parser const &parser, std::string const &filename, std::regex const &pattern) {
if (filename.empty()) {
std::cerr << "Missing filename" << std::endl;
parser.display_help(conventions);
exit(-1);
}
std::ifstream file(filename);
if (!file.is_open()) {
std::cerr << "Could not open file: \"" << filename << '"' << std::endl;
exit(-1);
}
for (std::string line; std::getline(file, line);) {
if (std::regex_search(line, pattern)) {
std::cout << line << std::endl;
}
}
file.close();
}
void run_grep(argument_parser::base_parser const &parser) {
auto filename = parser.get_optional<std::string>("file");
auto pattern = parser.get_optional<std::regex>("grep");
if (filename && pattern) {
grep(parser, filename.value(), pattern.value());
} else if (filename) {
std::cerr << "Missing grep pattern" << std::endl;
parser.display_help(conventions);
exit(-1);
} else if (pattern) {
std::cerr << "Missing filename" << std::endl;
parser.display_help(conventions);
exit(-1);
}
}
void run_store_point(argument_parser::base_parser const &parser) {
auto point = parser.get_optional<Point>("store-point");
if (point) {
std::cout << "Point(" << point->x << ", " << point->y << ")" << std::endl;
}
}
int v2Examples() {
using namespace argument_parser::v2::flags;
argument_parser::v2::parser parser{ false };
parser.add_argument<std::string>(
{{ShortArgument, "e"}, {LongArgument, "echo"}, {Action, echo}, {HelpText, "echoes given variable"}});
parser.add_argument<Point>({{ShortArgument, "ep"}, {LongArgument, "echo-point"}, {Action, echo_point}});
parser.add_argument<std::string>({
// stores string for f/file flag
{ShortArgument, "f"},
{LongArgument, "file"},
{HelpText, "File to grep, required only if using grep"},
// if no action, falls to store operation with given type.
});
parser.add_argument<std::regex>({
// stores string for g/grep flag
{ShortArgument, "g"},
{LongArgument, "grep"},
{HelpText, "Grep pattern, required only if using file"},
// same as 'file' flag
});
parser.add_argument<std::string>(
{{ShortArgument, "c"}, {LongArgument, "cat"}, {Action, cat}, {HelpText, "Prints the content of the file"}}
);
parser.add_argument<Point>({
// { ShortArgument, "sp" }, // now if ShortArgument or LongArgument is missing, it will use it for the other.
{LongArgument, "store-point"},
{Required, true} // makes this flag required
});
parser.add_argument({{ShortArgument, "v"}, {LongArgument, "verbose"}});
parser.add_argument<std::string>({
{Positional, "input"},
{HelpText, "Input file to process"},
{Required, true},
});
parser.add_argument<std::string>({
{Positional, "output"},
{HelpText, "Output file path"},
});
parser.add_argument<std::vector<Point>>({{LongArgument, "points"}, {HelpText, "List of points to store"}});
parser.on_complete(::run_grep);
parser.on_complete(::run_store_point);
parser.on_complete([](argument_parser::base_parser const &p) {
auto input = p.get_optional<std::string>("input");
auto output = p.get_optional<std::string>("output");
if (input) {
std::cout << "Input: " << input.value() << std::endl;
}
if (output) {
std::cout << "Output: " << output.value() << std::endl;
}
});
parser.handle_arguments(conventions);
return 0;
}
auto unique_copy(std::unique_ptr<std::string> ptr) {
std::cout << *ptr << std::endl;
}
auto unique_reference(std::unique_ptr<std::string> const& ptr) {
std::cout << *ptr << std::endl;
}
auto unique_move(std::unique_ptr<std::string>&& ptr) {
std::cout << *ptr << std::endl;
}
template<typename T>
T return_example(std::function<T()> func) {
if constexpr (std::is_same_v<void, T>) {
return func();
} else {
return func();
}
}
template<typename T>
void log_result(std::function<T()> func) {
if constexpr (std::is_same_v<void, T>) {
func();
} else {
std::cout << "result: " << func() << std::endl;
}
}
int main(int argc, char **argv) {
try {
return_example<void>([]{});
return v2Examples();
} catch (std::exception const &e) {
std::cout << e.what() << std::endl;
}
}

View File

@@ -50,7 +50,8 @@ namespace argument_parser::conventions::implementations {
return "/"; return "/";
} }
std::pair<std::string, std::string> windows_argument_convention::make_help_text(std::string const &short_arg, std::string const &long_arg, std::pair<std::string, std::string> windows_argument_convention::make_help_text(std::string const &short_arg,
std::string const &long_arg,
bool requires_value) const { bool requires_value) const {
std::string s_part = ""; std::string s_part = "";
if (short_arg != "-" && short_arg != "") { if (short_arg != "-" && short_arg != "") {
@@ -129,7 +130,8 @@ namespace argument_parser::conventions::implementations {
} }
std::pair<std::string, std::string> windows_kv_argument_convention::make_help_text(std::string const &short_arg, std::pair<std::string, std::string> windows_kv_argument_convention::make_help_text(std::string const &short_arg,
std::string const &long_arg, bool requires_value) const { std::string const &long_arg,
bool requires_value) const {
std::string s_part = ""; std::string s_part = "";
if (short_arg != "-" && short_arg != "") { if (short_arg != "-" && short_arg != "") {
s_part += short_prec() + short_arg; s_part += short_prec() + short_arg;

View File

@@ -36,8 +36,7 @@ namespace argument_parser {
} }
fake_parser::fake_parser(std::string const &program_name, std::initializer_list<std::string> const &arguments) fake_parser::fake_parser(std::string const &program_name, std::initializer_list<std::string> const &arguments)
: fake_parser(program_name, std::vector<std::string>(arguments)) { : fake_parser(program_name, std::vector<std::string>(arguments)) {}
}
void fake_parser::set_program_name(std::string const &program_name) { void fake_parser::set_program_name(std::string const &program_name) {
set_program_name(program_name); set_program_name(program_name);
@@ -46,5 +45,5 @@ namespace argument_parser {
void fake_parser::set_parsed_arguments(std::vector<std::string> const &parsed_arguments) { void fake_parser::set_parsed_arguments(std::vector<std::string> const &parsed_arguments) {
ref_parsed_args() = parsed_arguments; ref_parsed_args() = parsed_arguments;
} }
} } // namespace v2
} // namespace argument_parser } // namespace argument_parser

View File

@@ -8,7 +8,9 @@
do { \ do { \
const int argc_name = *_NSGetArgc(); \ const int argc_name = *_NSGetArgc(); \
if (char **argv_name = *_NSGetArgv(); argc_name > 0 && argv_name != nullptr && argv_name[0] != nullptr) { \ if (char **argv_name = *_NSGetArgv(); argc_name > 0 && argv_name != nullptr && argv_name[0] != nullptr) { \
do { before_for; } while(false); \ do { \
before_for; \
} while (false); \
for (int i = 1; i < argc_name; ++i) { \ for (int i = 1; i < argc_name; ++i) { \
for_body \ for_body \
} \ } \

View File

@@ -1,420 +0,0 @@
#include <argparse>
#include <array>
#include <cassert>
#include <exception>
#include <functional>
#include <iostream>
#include <string>
#include <vector>
const std::initializer_list<argument_parser::conventions::convention const *const> conventions = {
&argument_parser::conventions::gnu_argument_convention,
&argument_parser::conventions::gnu_equal_argument_convention,
};
namespace v2_test {
class fake_parser : public argument_parser::v2::base_parser {
public:
fake_parser(std::string const &program_name, std::initializer_list<std::string> const &arguments) {
set_program_name(program_name);
ref_parsed_args() = std::vector<std::string>(arguments);
prepare_help_flag();
}
};
} // namespace v2_test
int tests_run = 0;
int tests_passed = 0;
void test_result(const char *name, bool passed) {
tests_run++;
if (passed) {
tests_passed++;
std::cout << " [PASS] " << name << std::endl;
} else {
std::cout << " [FAIL] " << name << std::endl;
}
}
// ============================================================
// V1 Tests (using argument_parser::fake_parser)
// ============================================================
void test_v1_single_positional_store() {
argument_parser::fake_parser parser("test", {"hello"});
parser.add_positional_argument<std::string>("greeting", "A greeting", false);
parser.handle_arguments(conventions);
auto val = parser.get_optional<std::string>("greeting");
test_result("v1: single positional store", val.has_value() && val.value() == "hello");
}
void test_v1_multiple_positionals_ordered() {
argument_parser::fake_parser parser("test", {"alpha", "beta", "gamma"});
parser.add_positional_argument<std::string>("first", "First arg", false);
parser.add_positional_argument<std::string>("second", "Second arg", false);
parser.add_positional_argument<std::string>("third", "Third arg", false);
parser.handle_arguments(conventions);
auto first = parser.get_optional<std::string>("first");
auto second = parser.get_optional<std::string>("second");
auto third = parser.get_optional<std::string>("third");
bool ok = first.has_value() && first.value() == "alpha" && second.has_value() && second.value() == "beta" &&
third.has_value() && third.value() == "gamma";
test_result("v1: multiple positionals preserve order", ok);
}
void test_v1_positional_with_explicit_position() {
argument_parser::fake_parser parser("test", {"first_val", "second_val"});
parser.add_positional_argument<std::string>("second", "Second", false, 1);
parser.add_positional_argument<std::string>("first", "First", false, 0);
parser.handle_arguments(conventions);
auto first = parser.get_optional<std::string>("first");
auto second = parser.get_optional<std::string>("second");
bool ok = first.has_value() && first.value() == "first_val" && second.has_value() && second.value() == "second_val";
test_result("v1: explicit position index", ok);
}
void test_v1_positional_typed_int() {
argument_parser::fake_parser parser("test", {"42"});
parser.add_positional_argument<int>("count", "A count", false);
parser.handle_arguments(conventions);
auto val = parser.get_optional<int>("count");
test_result("v1: positional with int type", val.has_value() && val.value() == 42);
}
void test_v1_positional_with_action() {
std::string captured;
argument_parser::fake_parser parser("test", {"world"});
auto action =
argument_parser::helpers::make_parametered_action<std::string>([&](std::string const &v) { captured = v; });
parser.add_positional_argument<std::string>("name", "A name", action, false);
parser.handle_arguments(conventions);
test_result("v1: positional with action", captured == "world");
}
void test_v1_mixed_named_and_positional() {
argument_parser::fake_parser parser("test", {"--verbose", "true", "myfile.txt"});
parser.add_argument<bool>("v", "verbose", "Verbose mode", false);
parser.add_positional_argument<std::string>("file", "Input file", false);
parser.handle_arguments(conventions);
auto verbose = parser.get_optional<bool>("verbose");
auto file = parser.get_optional<std::string>("file");
bool ok = verbose.has_value() && verbose.value() == true && file.has_value() && file.value() == "myfile.txt";
test_result("v1: mixed named and positional args", ok);
}
void test_v1_positional_after_named() {
argument_parser::fake_parser parser("test", {"-n", "5", "output.txt"});
parser.add_argument<int>("n", "number", "A number", false);
parser.add_positional_argument<std::string>("output", "Output file", false);
parser.handle_arguments(conventions);
auto number = parser.get_optional<int>("number");
auto output = parser.get_optional<std::string>("output");
bool ok = number.has_value() && number.value() == 5 && output.has_value() && output.value() == "output.txt";
test_result("v1: positional after named args", ok);
}
void test_v1_positional_between_named() {
argument_parser::fake_parser parser("test", {"-a", "1", "positional_val", "--beta", "2"});
parser.add_argument<int>("a", "alpha", "Alpha", false);
parser.add_argument<int>("b", "beta", "Beta", false);
parser.add_positional_argument<std::string>("middle", "Middle arg", false);
parser.handle_arguments(conventions);
auto alpha = parser.get_optional<int>("alpha");
auto beta = parser.get_optional<int>("beta");
auto middle = parser.get_optional<std::string>("middle");
bool ok = alpha.has_value() && alpha.value() == 1 && beta.has_value() && beta.value() == 2 && middle.has_value() &&
middle.value() == "positional_val";
test_result("v1: positional between named args", ok);
}
void test_v1_double_dash_separator() {
argument_parser::fake_parser parser("test", {"--", "-not-a-flag"});
parser.add_positional_argument<std::string>("item", "An item", false);
parser.handle_arguments(conventions);
auto val = parser.get_optional<std::string>("item");
test_result("v1: -- separator treats next as positional", val.has_value() && val.value() == "-not-a-flag");
}
void test_v1_double_dash_multiple() {
argument_parser::fake_parser parser("test", {"--name", "hello", "--", "--weird", "-x"});
parser.add_argument<std::string>("n", "name", "A name", false);
parser.add_positional_argument<std::string>("first", "First", false);
parser.add_positional_argument<std::string>("second", "Second", false);
parser.handle_arguments(conventions);
auto name = parser.get_optional<std::string>("name");
auto first = parser.get_optional<std::string>("first");
auto second = parser.get_optional<std::string>("second");
bool ok = name.has_value() && name.value() == "hello" && first.has_value() && first.value() == "--weird" &&
second.has_value() && second.value() == "-x";
test_result("v1: -- separator with multiple positionals", ok);
}
void test_v1_required_positional_missing() {
argument_parser::fake_parser parser("test", {});
parser.add_positional_argument<std::string>("file", "A file", true);
bool threw = false;
try {
// check_for_required_arguments calls std::exit(1) so we can't easily test it
// instead, test that handle_arguments doesn't crash when positionals are provided
parser.handle_arguments(conventions);
} catch (...) {
threw = true;
}
// Note: required check calls std::exit(1), so if we get here the arg wasn't required-checked
// This test just verifies setup doesn't crash. The exit behavior is tested manually.
test_result("v1: required positional setup (no crash)", true);
}
void test_v1_unexpected_positional_throws() {
argument_parser::fake_parser parser("test", {"unexpected"});
// no positional args defined, but a bare token is provided
bool threw = false;
try {
parser.handle_arguments(conventions);
} catch (const std::runtime_error &) {
threw = true;
}
test_result("v1: unexpected positional throws", threw);
}
void test_v1_duplicate_positional_name_throws() {
argument_parser::fake_parser parser("test", {"a", "b"});
parser.add_positional_argument<std::string>("file", "A file", false);
bool threw = false;
try {
parser.add_positional_argument<std::string>("file", "Duplicate", false);
} catch (const std::runtime_error &) {
threw = true;
}
test_result("v1: duplicate positional name throws", threw);
}
void test_v1_positional_on_complete() {
std::string captured_file;
argument_parser::fake_parser parser("test", {"data.csv"});
parser.add_positional_argument<std::string>("file", "Input file", false);
parser.on_complete([&](argument_parser::base_parser const &p) {
auto val = p.get_optional<std::string>("file");
if (val)
captured_file = val.value();
});
parser.handle_arguments(conventions);
test_result("v1: positional accessible in on_complete", captured_file == "data.csv");
}
// ============================================================
// V2 Tests (using v2_test::fake_parser)
// ============================================================
void test_v2_single_positional() {
using namespace argument_parser::v2::flags;
v2_test::fake_parser parser("test", {"hello"});
parser.add_argument<std::string>({{Positional, "greeting"}, {HelpText, "A greeting"}});
parser.handle_arguments(conventions);
auto val = parser.get_optional<std::string>("greeting");
test_result("v2: single positional store", val.has_value() && val.value() == "hello");
}
void test_v2_positional_required() {
using namespace argument_parser::v2::flags;
v2_test::fake_parser parser("test", {"value"});
parser.add_argument<std::string>({{Positional, "arg"}, {Required, true}, {HelpText, "Required arg"}});
parser.handle_arguments(conventions);
auto val = parser.get_optional<std::string>("arg");
test_result("v2: required positional", val.has_value() && val.value() == "value");
}
void test_v2_positional_with_position() {
using namespace argument_parser::v2::flags;
v2_test::fake_parser parser("test", {"first_val", "second_val"});
parser.add_argument<std::string>({{Positional, "second"}, {Position, 1}, {HelpText, "Second"}});
parser.add_argument<std::string>({{Positional, "first"}, {Position, 0}, {HelpText, "First"}});
parser.handle_arguments(conventions);
auto first = parser.get_optional<std::string>("first");
auto second = parser.get_optional<std::string>("second");
bool ok = first.has_value() && first.value() == "first_val" && second.has_value() && second.value() == "second_val";
test_result("v2: positional with explicit Position", ok);
}
void test_v2_positional_typed_int() {
using namespace argument_parser::v2::flags;
v2_test::fake_parser parser("test", {"99"});
parser.add_argument<int>({{Positional, "count"}, {HelpText, "A count"}});
parser.handle_arguments(conventions);
auto val = parser.get_optional<int>("count");
test_result("v2: positional with int type", val.has_value() && val.value() == 99);
}
void test_v2_mixed_named_and_positional() {
using namespace argument_parser::v2::flags;
v2_test::fake_parser parser("test", {"--output", "out.txt", "input.txt"});
parser.add_argument<std::string>({{ShortArgument, "o"}, {LongArgument, "output"}, {HelpText, "Output file"}});
parser.add_argument<std::string>({{Positional, "input"}, {HelpText, "Input file"}});
parser.handle_arguments(conventions);
auto output = parser.get_optional<std::string>("output");
auto input = parser.get_optional<std::string>("input");
bool ok = output.has_value() && output.value() == "out.txt" && input.has_value() && input.value() == "input.txt";
test_result("v2: mixed named and positional", ok);
}
void test_v2_positional_with_action() {
using namespace argument_parser::v2::flags;
std::string captured;
v2_test::fake_parser parser("test", {"world"});
parser.add_argument<std::string>({{Positional, "name"},
{Action, argument_parser::helpers::make_parametered_action<std::string>(
[&](std::string const &v) { captured = v; })},
{HelpText, "A name"}});
parser.handle_arguments(conventions);
test_result("v2: positional with action", captured == "world");
}
void test_v2_double_dash_separator() {
using namespace argument_parser::v2::flags;
v2_test::fake_parser parser("test", {"--", "--not-a-flag"});
parser.add_argument<std::string>({{Positional, "item"}, {HelpText, "An item"}});
parser.handle_arguments(conventions);
auto val = parser.get_optional<std::string>("item");
test_result("v2: -- separator", val.has_value() && val.value() == "--not-a-flag");
}
void test_v2_positional_auto_help_text() {
using namespace argument_parser::v2::flags;
v2_test::fake_parser parser("test", {"42"});
// no HelpText provided — should auto-generate from traits
parser.add_argument<int>({{Positional, "count"}});
parser.handle_arguments(conventions);
auto val = parser.get_optional<int>("count");
test_result("v2: positional auto help text (no crash)", val.has_value() && val.value() == 42);
}
void test_v2_multiple_positionals_and_named() {
using namespace argument_parser::v2::flags;
v2_test::fake_parser parser("test", {"-v", "src.txt", "dst.txt"});
parser.add_argument({{ShortArgument, "v"}, {LongArgument, "verbose"}});
parser.add_argument<std::string>({{Positional, "source"}, {HelpText, "Source"}});
parser.add_argument<std::string>({{Positional, "destination"}, {HelpText, "Destination"}});
parser.handle_arguments(conventions);
auto verbose = parser.get_optional<bool>("verbose");
auto source = parser.get_optional<std::string>("source");
auto dest = parser.get_optional<std::string>("destination");
bool ok = verbose.has_value() && source.has_value() && source.value() == "src.txt" && dest.has_value() &&
dest.value() == "dst.txt";
test_result("v2: multiple positionals with named flag", ok);
}
void test_v2_on_complete_with_positional() {
using namespace argument_parser::v2::flags;
std::string captured;
v2_test::fake_parser parser("test", {"payload"});
parser.add_argument<std::string>({{Positional, "data"}, {HelpText, "Data"}});
parser.on_complete([&](argument_parser::base_parser const &p) {
auto val = p.get_optional<std::string>("data");
if (val)
captured = val.value();
});
parser.handle_arguments(conventions);
test_result("v2: positional accessible in on_complete", captured == "payload");
}
// ============================================================
// Main
// ============================================================
int main() {
std::cout << "=== V1 Positional Argument Tests ===" << std::endl;
std::array<std::function<void()>, 13> v1Tests {
test_v1_single_positional_store,
test_v1_multiple_positionals_ordered,
test_v1_positional_with_explicit_position,
test_v1_positional_typed_int,
test_v1_positional_with_action,
test_v1_mixed_named_and_positional,
test_v1_positional_after_named,
test_v1_positional_between_named,
test_v1_double_dash_separator,
test_v1_double_dash_multiple,
test_v1_unexpected_positional_throws,
test_v1_duplicate_positional_name_throws,
test_v1_positional_on_complete
};
for (auto const& test : v1Tests) {
try {
test();
} catch(std::exception const& e) {
std::cout << "test failed: " << e.what() << std::endl;
}
}
std::cout << "\n=== V2 Positional Argument Tests ===" << std::endl;
std::array<std::function<void()>, 10> v2Tests{
test_v2_single_positional,
test_v2_positional_required,
test_v2_positional_with_position,
test_v2_positional_typed_int,
test_v2_mixed_named_and_positional,
test_v2_positional_with_action,
test_v2_double_dash_separator,
test_v2_positional_auto_help_text,
test_v2_multiple_positionals_and_named,
test_v2_on_complete_with_positional
};
for (auto const& test : v2Tests) {
try {
test();
} catch(std::exception const& e) {
std::cout << "test failed: " << e.what() << std::endl;
}
}
std::cout << "\n=== Results: " << tests_passed << "/" << tests_run << " passed ===" << std::endl;
return (tests_passed == tests_run) ? 0 : 1;
}