Merge remote-tracking branch 'refs/remotes/origin/main'

main
Brett 2025-07-15 14:15:30 -04:00
commit 8b6379ff1f
23 changed files with 1771 additions and 439 deletions

View File

@ -1,246 +1,249 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="BackendCodeEditorSettings">
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSmartPointerVsMakeFunction/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCStyleCast/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionalStyleCast/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReinterpretCastFromVoidPtr/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExplicitConvertingConstructor/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExplicitConversionOperator/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDiscardedPostfixOperatorResult/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConstValueFunctionReturnType/@EntryIndexedValue" value="SUGGESTION" 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/=CppLocalVariableMayBeConst/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterMayBeConst/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVariableCanBeMadeConstexpr/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterMayBeConstPtrOrRef/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPassValueParameterByConstReference/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppThrowExpressionCanBeReplacedWithRethrow/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppZeroConstantCanBeReplacedWithNullptr/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCompileTimeConstantCanBeReplacedWithBooleanConstant/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIfCanBeReplacedByConstexprIf/@EntryIndexedValue" value="SUGGESTION" 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/=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/=CppClassCanBeFinal/@EntryIndexedValue" value="HINT" 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/=CppUseAlgorithmWithCount/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseRangeAlgorithm/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseElementsView/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseStdSize/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppForLoopCanBeReplacedWithWhile/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppJoinDeclarationAndAssignment/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReplaceTieWithStructuredBinding/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReplaceMemsetWithZeroInitialization/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAssociativeContains/@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/=CppTooWideScope/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTooWideScopeInitStatement/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantNamespaceDefinition/@EntryIndexedValue" value="SUGGESTION" 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/=CppFunctionIsNotImplemented/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrivateSpecialMemberFunctionIsNotImplemented/@EntryIndexedValue" value="WARNING" 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/=CppPolymorphicClassWithNonVirtualPublicDestructor/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAbstractClassWithoutSpecifier/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIncompleteSwitchStatement/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultCaseNotHandledInSwitchStatement/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyErroneousEmptyStatements/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppExpressionWithoutSideEffects/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNoDiscardExpression/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionResultShouldBeUsed/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingKeywordThrow/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDependentTypeWithoutTypenameKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDependentTemplateWithoutTemplateKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppImplicitDefaultConstructorNotAvailable/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeedsConstructorBecauseOfUninitializedMember/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUninitializedNonStaticDataMember/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRangeBasedForIncompatibleReference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppZeroValuedExpressionUsedAsNullPointer/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyUnintendedObjectSlicing/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyUninitializedMember/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorDisambiguatedAsFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVirtualFunctionInFinalClass/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMustBePublicVirtualToImplementInterface/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclarationSpecifierWithoutDeclarators/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEmptyDeclaration/@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/=CppMismatchedClassTags/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUsingResultOfAssignmentAsCondition/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIntegralToPointerConversion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPointerToIntegralConversion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIncompatiblePointerConversion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPointerConversionDropsQualifiers/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStringLiteralToCharPointerConversion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExceptionSafeResourceAcquisition/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVirtualFunctionCallInsideCtor/@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/=CppInvalidLineContinuation/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfBadFormat/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfRiskyFormat/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfMissedArg/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfExtraArg/@EntryIndexedValue" value="WARNING" 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/=CppDeprecatedEntity/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingIncludeGuard/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenSyntaxError/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenUnresolvedReference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenUndocumentedParameter/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeletingVoidPointer/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBooleanIncrementExpression/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeprecatedRegisterStorageClassSpecifier/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIdenticalOperandsInBinaryExpression/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEqualOperandsInBinaryExpression/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedefinitionOfDefaultArgumentInOverrideFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnnamedNamespaceInHeaderFile/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterNamesMismatch/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultedSpecialMemberFunctionIsImplicitlyDeleted/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNodiscardFunctionWithoutReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantComplexityInComparison/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAbstractFinalClass/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSpecialFunctionWithoutNoexceptSpecification/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnsignedZeroComparison/@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/=CppRedundantQualifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantAccessSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAccessSpecifierWithNoDeclarations/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTypenameKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTemplateKeyword/@EntryIndexedValue" value="WARNING" 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/=CppRedundantControlFlowJump/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantEmptyStatement/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantEmptyDeclaration/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantParentheses/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantLambdaParameterList/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantCastExpression/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppHeaderHasBeenAlreadyIncluded/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateArgumentsCanBeDeduced/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTemplateArguments/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticSpecifierOnAnonymousNamespaceMember/@EntryIndexedValue" value="SUGGESTION" 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/=CppRedundantBaseClassAccessSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantInlineSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantConstSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantBooleanExpressionArgument/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantVoidArgumentList/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantMemberInitializer/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantBaseClassInitializer/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConstParameterInDeclaration/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVolatileParameterInDeclaration/@EntryIndexedValue" value="SUGGESTION" 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/=CppRedundantElaboratedTypeSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantDereferencingAndTakingAddress/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantConditionalExpression/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConditionalExpressionCanBeSimplified/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantExportKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantZeroInitializerInAggregateInitialization/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUserDefinedLiteralSuffixDoesNotStartWithUnderscore/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassIsIncomplete/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateParameterShadowing/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMutableSpecifierOnReferenceMember/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultInitializationWithNoUserConstructor/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppExplicitSpecializationInNonNamespaceScope/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnionMemberOfReferenceType/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUninitializedDependentBaseClass/@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/=CppCoroutineCallResolveError/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAwaiterTypeIsNotClass/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppOutParameterMustBeWritten/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppWarningDirective/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticAssertFailure/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEvaluationFailure/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTypeAliasNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConceptNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnumeratorNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLambdaCaptureNeverUsed/@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/=CppParameterNeverUsed/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateParameterNeverUsed/@EntryIndexedValue" value="HINT" 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/=CppLocalVariableMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppObjectMemberMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSomeObjectMembersMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorUsedBeforeInitialization/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnusedIncludeDirective/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNotAllPathsReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CDeclarationWithImplicitIntType/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionDoesntReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReturnNoValueInNonVoidFunction/@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/=CppDereferenceOperatorLimitExceeded/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppForwardEnumDeclarationWithoutUnderlyingType/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnmatchedPragmaRegionDirective/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnmatchedPragmaEndRegionDirective/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticDataMemberInUnnamedStruct/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultIsUsedAsIdentifier/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLongFloat/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtReinterpretCastFromNullptr/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtBindingRValueToLvalueReference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtAddressOfClassRValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtDoubleUserConversionInCopyInit/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtCopyElisionInCopyInitDeclarator/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtNotInitializedStaticConstLocalVar/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRemoveRedundantBraces/@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/=CppEnforceForStatementBraces/@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/=CppEnforceDoStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" 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/=CppEnforceNestedNamespacesStyle/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceTypeAliasCodeStyle/@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/=CppMemberInitializersOrder/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceOverridingFunctionStyle/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceOverridingDestructorStyle/@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/=CppEnforceCVQualifiersPlacement/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceCVQualifiersOrder/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnnecessaryWhitespace/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTabsAreDisallowed/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantConditions/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFANullDereference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFANotInitializedField/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALoopConditionNotUpdated/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFADeletedPointer/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAMemoryLeak/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAInvalidatedMemory/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALocalValueEscapesScope/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALocalValueEscapesFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantParameter/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantFunctionResult/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassCanBeFinal/@EntryIndexedValue" value="DO_NOT_SHOW" 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/=CppDFAUnreachableCode/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnreachableFunctionCall/@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/=CppDFAUnusedValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnreadVariable/@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="DO_NOT_SHOW" 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/=StringLiteralTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CommentTypo/@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/=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="DO_NOT_SHOW" 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/CodeStyle/Naming/CppNaming/Rules/=Enums/@EntryIndexedValue" value="&lt;NamingElement Priority=&quot;3&quot;&gt;&lt;Descriptor Static=&quot;Indeterminate&quot; Constexpr=&quot;Indeterminate&quot; Const=&quot;Indeterminate&quot; Volatile=&quot;Indeterminate&quot; Accessibility=&quot;NOT_APPLICABLE&quot;&gt;&lt;type Name=&quot;enum&quot; /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect=&quot;True&quot; WarnAboutPrefixesAndSuffixes=&quot;False&quot; Prefix=&quot;&quot; Suffix=&quot;&quot; Style=&quot;AA_BB&quot; /&gt;&lt;/NamingElement&gt;" 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/Naming/CppNaming/Rules/=Class_0020and_0020struct_0020fields/@EntryIndexedValue" value="&lt;NamingElement Priority=&quot;11&quot;&gt;&lt;Descriptor Static=&quot;Indeterminate&quot; Constexpr=&quot;Indeterminate&quot; Const=&quot;Indeterminate&quot; Volatile=&quot;Indeterminate&quot; Accessibility=&quot;NOT_APPLICABLE&quot;&gt;&lt;type Name=&quot;class field&quot; /&gt;&lt;type Name=&quot;struct field&quot; /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect=&quot;True&quot; WarnAboutPrefixesAndSuffixes=&quot;False&quot; Prefix=&quot;m_&quot; Suffix=&quot;&quot; Style=&quot;aa_bb&quot; /&gt;&lt;/NamingElement&gt;" type="string" />
<option name="/Default/CodeStyle/Naming/CppNaming/Rules/=Enums/@EntryIndexedValue" value="&lt;NamingElement Priority=&quot;3&quot;&gt;&lt;Descriptor Static=&quot;Indeterminate&quot; Constexpr=&quot;Indeterminate&quot; Const=&quot;Indeterminate&quot; Volatile=&quot;Indeterminate&quot; Accessibility=&quot;NOT_APPLICABLE&quot;&gt;&lt;type Name=&quot;enum&quot; /&gt;&lt;/Descriptor&gt;&lt;Policy Inspect=&quot;True&quot; WarnAboutPrefixesAndSuffixes=&quot;False&quot; Prefix=&quot;&quot; Suffix=&quot;&quot; Style=&quot;AA_BB&quot; /&gt;&lt;/NamingElement&gt;" type="string" />
</component>
</project>

View File

@ -0,0 +1,8 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="CppClassCanBeFinal" enabled="false" level="HINT" enabled_by_default="false" />
<inspection_tool class="CppDeclarationHidesUncapturedLocal" enabled="false" level="HINT" enabled_by_default="false" />
<inspection_tool class="CppTooWideScopeInitStatement" enabled="false" level="HINT" enabled_by_default="false" />
</profile>
</component>

View File

@ -27,7 +27,7 @@ macro(compile_options target_name)
sanitizers(${target_name})
endmacro()
project(blt-gp VERSION 0.4.9)
project(blt-gp VERSION 0.5.28)
include(CTest)
@ -37,7 +37,8 @@ option(ENABLE_TSAN "Enable the thread data race sanitizer" OFF)
option(BUILD_EXAMPLES "Build example programs. This will build with CTest" OFF)
option(BUILD_GP_TESTS "Build test programs." OFF)
option(DEBUG_LEVEL "Enable debug features which prints extra information to the console, might slow processing down. [0, 3)" 0)
option(TRACK_ALLOCATIONS "Track total allocations. Can be accessed with blt::gp::tracker" OFF)
option(BLT_GP_DEBUG_CHECK_TREES "Enable checking of trees after every operation" OFF)
option(BLT_GP_DEBUG_TRACK_ALLOCATIONS "Track total allocations. Can be accessed with blt::gp::tracker" OFF)
set(CMAKE_CXX_STANDARD 17)
@ -122,5 +123,6 @@ if (${BUILD_GP_TESTS})
blt_add_project(blt-symbolic-regression tests/symbolic_regression_test.cpp test)
blt_add_project(blt-drop tests/drop_test.cpp test)
blt_add_project(blt-drop-2-type tests/2_type_drop_test.cpp test)
blt_add_project(blt-serialization tests/serialization_test.cpp test)
endif ()

View File

@ -0,0 +1,230 @@
bool type_aware_crossover_t::apply(gp_program& program, const tree_t& p1, const tree_t& p2, tree_t& c1, tree_t& c2)
{
if (p1.size() < config.min_tree_size || p2.size() < config.min_tree_size)
return false;
tree_t::subtree_point_t point1, point2;
if (config.traverse)
{
point1 = p1.select_subtree_traverse(config.terminal_chance, config.depth_multiplier);
if (const auto val = p2.select_subtree_traverse(point1.type, config.max_crossover_tries, config.terminal_chance, config.depth_multiplier))
point2 = *val;
else
return false;
} else
{
point1 = p1.select_subtree(config.terminal_chance);
if (const auto val = p2.select_subtree(point1.type, config.max_crossover_tries, config.terminal_chance))
point2 = *val;
else
return false;
}
const auto& p1_operator = p1.get_operator(point1.pos);
const auto& p2_operator = p2.get_operator(point2.pos);
// If either is a terminal (value), just do normal subtree crossover
if (p1_operator.is_value() || p2_operator.is_value())
{
c1.swap_subtrees(point1, c2, point2);
return true;
}
const auto& p1_info = program.get_operator_info(p1_operator.id());
const auto& p2_info = program.get_operator_info(p2_operator.id());
// Find the child subtrees of both operators
thread_local tracked_vector<tree_t::child_t> children_data_p1;
thread_local tracked_vector<tree_t::child_t> children_data_p2;
children_data_p1.clear();
children_data_p2.clear();
p1.find_child_extends(children_data_p1, point1.pos, p1_info.argument_types.size());
p2.find_child_extends(children_data_p2, point2.pos, p2_info.argument_types.size());
// Check if all types are identical but possibly in different order
bool same_types_different_order = p1_info.argument_types.size() == p2_info.argument_types.size();
if (same_types_different_order)
{
// Create frequency counts of types in both operators
std::unordered_map<type_id, size_t> type_counts_p1;
std::unordered_map<type_id, size_t> type_counts_p2;
for (const auto& type : p1_info.argument_types)
type_counts_p1[type.id]++;
for (const auto& type : p2_info.argument_types)
type_counts_p2[type.id]++;
// Check if the type counts match
for (const auto& [type, count] : type_counts_p1)
{
if (type_counts_p2[type] != count)
{
same_types_different_order = false;
break;
}
}
}
if (same_types_different_order)
{
// Create a mapping from p1's argument positions to p2's positions
std::vector<size_t> arg_mapping(p1_info.argument_types.size(), (size_t)-1);
std::vector<bool> p2_used(p2_info.argument_types.size(), false);
// First pass: match exact types in order
for (size_t i = 0; i < p1_info.argument_types.size(); i++)
{
for (size_t j = 0; j < p2_info.argument_types.size(); j++)
{
if (!p2_used[j] && p1_info.argument_types[i].id == p2_info.argument_types[j].id)
{
arg_mapping[i] = j;
p2_used[j] = true;
break;
}
}
}
// Copy operators first
auto& c1_temp = tree_t::get_thread_local(program);
auto& c2_temp = tree_t::get_thread_local(program);
c1_temp.clear(program);
c2_temp.clear(program);
// Create new operators with the same return types
c1_temp.insert_operator({
program.get_typesystem().get_type(p2_info.return_type).size(),
p2_operator.id(),
program.is_operator_ephemeral(p2_operator.id()),
program.get_operator_flags(p2_operator.id())
});
c2_temp.insert_operator({
program.get_typesystem().get_type(p1_info.return_type).size(),
p1_operator.id(),
program.is_operator_ephemeral(p1_operator.id()),
program.get_operator_flags(p1_operator.id())
});
// Copy child subtrees according to the mapping
for (size_t i = 0; i < p1_info.argument_types.size(); i++)
{
auto& p1_child = children_data_p1[i];
auto& p2_child = children_data_p2[arg_mapping[i]];
tree_t p1_subtree(program);
tree_t p2_subtree(program);
p1.copy_subtree(tree_t::subtree_point_t(p1_child.start), p1_child.end, p1_subtree);
p2.copy_subtree(tree_t::subtree_point_t(p2_child.start), p2_child.end, p2_subtree);
c1_temp.insert_subtree(tree_t::subtree_point_t(c1_temp.size()), p2_subtree);
c2_temp.insert_subtree(tree_t::subtree_point_t(c2_temp.size()), p1_subtree);
}
// Replace the original subtrees with our new reordered ones
c1.replace_subtree(point1, c1_temp);
c2.replace_subtree(point2, c2_temp);
}
else
{
// If types don't match exactly, fall back to simple operator swap
// but we need to ensure the children are compatible
// Create new operators with swapped operators but appropriate children
auto& c1_temp = tree_t::get_thread_local(program);
auto& c2_temp = tree_t::get_thread_local(program);
c1_temp.clear(program);
c2_temp.clear(program);
c1_temp.insert_operator({
program.get_typesystem().get_type(p2_info.return_type).size(),
p2_operator.id(),
program.is_operator_ephemeral(p2_operator.id()),
program.get_operator_flags(p2_operator.id())
});
c2_temp.insert_operator({
program.get_typesystem().get_type(p1_info.return_type).size(),
p1_operator.id(),
program.is_operator_ephemeral(p1_operator.id()),
program.get_operator_flags(p1_operator.id())
});
// Create a mapping of which children we can reuse and which need to be regenerated
for (size_t i = 0; i < p2_info.argument_types.size(); i++)
{
const auto& needed_type = p2_info.argument_types[i];
bool found_match = false;
// Try to find a matching child from p1
for (size_t j = 0; j < p1_info.argument_types.size(); j++)
{
if (needed_type.id == p1_info.argument_types[j].id)
{
// Copy this child subtree from p1
auto& p1_child = children_data_p1[j];
tree_t p1_subtree(program);
p1.copy_subtree(tree_t::subtree_point_t(p1_child.start), p1_child.end, p1_subtree);
c1_temp.insert_subtree(tree_t::subtree_point_t(c1_temp.size()), p1_subtree);
found_match = true;
break;
}
}
if (!found_match)
{
// If no matching child, we need to generate a new subtree of the correct type
auto& tree = tree_t::get_thread_local(program);
tree.clear(program);
config.generator.get().generate(tree, {program, needed_type.id, config.replacement_min_depth, config.replacement_max_depth});
c1_temp.insert_subtree(tree_t::subtree_point_t(c1_temp.size()), tree);
}
}
// Do the same for the other direction (c2)
for (size_t i = 0; i < p1_info.argument_types.size(); i++)
{
const auto& needed_type = p1_info.argument_types[i];
bool found_match = false;
// Try to find a matching child from p2
for (size_t j = 0; j < p2_info.argument_types.size(); j++)
{
if (needed_type.id == p2_info.argument_types[j].id)
{
// Copy this child subtree from p2
auto& p2_child = children_data_p2[j];
tree_t p2_subtree(program);
p2.copy_subtree(tree_t::subtree_point_t(p2_child.start), p2_child.end, p2_subtree);
c2_temp.insert_subtree(tree_t::subtree_point_t(c2_temp.size()), p2_subtree);
found_match = true;
break;
}
}
if (!found_match)
{
// If no matching child, we need to generate a new subtree of the correct type
auto& tree = tree_t::get_thread_local(program);
tree.clear(program);
config.generator.get().generate(tree, {program, needed_type.id, config.replacement_min_depth, config.replacement_max_depth});
c2_temp.insert_subtree(tree_t::subtree_point_t(c2_temp.size()), tree);
}
}
// Replace the original subtrees with our new ones
c1.replace_subtree(point1, c1_temp);
c2.replace_subtree(point2, c2_temp);
}
#if BLT_DEBUG_LEVEL >= 2
if (!c1.check(detail::debug::context_ptr) || !c2.check(detail::debug::context_ptr))
throw std::runtime_error("Tree check failed");
#endif
return true;
}

44
default.nix Normal file
View File

@ -0,0 +1,44 @@
{ pkgs ? (import <nixpkgs> {
config.allowUnfree = true;
config.segger-jlink.acceptLicense = true;
}), ... }:
pkgs.mkShell
{
buildInputs = with pkgs; [
cmake
gcc
clang
emscripten
ninja
renderdoc
valgrind
gtest
opentelemetry-cpp
opentelemetry-cpp.dev
];
nativeBuildInputs = with pkgs; [
pkg-config
opentelemetry-cpp
opentelemetry-cpp.dev
];
propagatedBuildInputs = with pkgs; [
abseil-cpp
protobuf
grpc
prometheus-cpp
prometheus-cpp.dev
openssl
openssl.dev
opentelemetry-cpp
opentelemetry-cpp.dev
civetweb
civetweb.dev
c-ares
c-ares.dev
nlohmann_json
glibc
glibc.dev
curl
];
LD_LIBRARY_PATH="/run/opengl-driver/lib:/run/opengl-driver-32/lib";
}

View File

@ -79,7 +79,7 @@ namespace blt::gp::example
BLT_DEBUG("Begin Generation Loop");
while (!program.should_terminate())
{
BLT_TRACE("------------{Begin Generation %ld}------------", program.get_current_generation());
BLT_TRACE("------------\\{Begin Generation {}}------------", program.get_current_generation());
BLT_TRACE("Creating next generation");
program.create_next_generation();
BLT_TRACE("Move to next generation");
@ -116,8 +116,8 @@ namespace blt::gp::example
mutation_sel = &sel;
if (reproduction_sel == nullptr)
reproduction_sel = &sel;
program.generate_population(program.get_typesystem().get_type<float>().id(), fitness_function_ref, *crossover_sel, *mutation_sel,
*reproduction_sel);
program.generate_initial_population(program.get_typesystem().get_type<float>().id());
program.setup_generational_evaluation(fitness_function_ref, *crossover_sel, *mutation_sel, *reproduction_sel);
}
void print_best(const size_t amount = 3)

View File

@ -21,7 +21,7 @@
#include <blt/gp/program.h>
#include <blt/profiling/profiler_v2.h>
#include <blt/gp/tree.h>
#include <blt/std/logging.h>
#include <blt/logging/logging.h>
#include <blt/format/format.h>
#include <blt/parse/argparse.h>
#include <iostream>
@ -191,7 +191,7 @@ void blt::gp::example::rice_classification_t::load_rice_data(const std::string_v
training_cases.insert(training_cases.end(), c.begin(), c.end());
training_cases.insert(training_cases.end(), o.begin(), o.end());
std::shuffle(training_cases.begin(), training_cases.end(), program.get_random());
BLT_INFO("Created testing set of size %ld, training set is of size %ld", testing_cases.size(), training_cases.size());
BLT_INFO("Created testing set of size {}, training set is of size {}", testing_cases.size(), training_cases.size());
}
blt::gp::confusion_matrix_t blt::gp::example::rice_classification_t::test_individual(const individual_t& individual) const

View File

@ -29,7 +29,10 @@ namespace blt::gp
{
namespace detail
{
static constexpr inline size_t MAX_ALIGNMENT = 8;
#ifndef BLT_GP_MAX_ALIGNMENT
#define BLT_GP_MAX_ALIGNMENT 8
#endif
static constexpr inline size_t MAX_ALIGNMENT = BLT_GP_MAX_ALIGNMENT;
#if BLT_DEBUG_LEVEL > 0
static void check_alignment(const size_t bytes, const std::string& message = "Invalid alignment")

48
include/blt/gp/defines.h Normal file
View File

@ -0,0 +1,48 @@
#pragma once
/*
* Copyright (C) 2024 Brett Terpstra
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef BLT_GP_DEFINES_H
#define BLT_GP_DEFINES_H
#include <blt/std/defines.h>
#if BLT_DEBUG_LEVEL > 0
#if defined(__has_include) &&__has_include(<opentelemetry/version.h>)
#define BLT_DEBUG_OTEL_ENABLED 1
#endif
#endif
#if BLT_DEBUG_LEVEL > 1
#define BLT_GP_DEBUG_TRACK_ALLOCATIONS
#endif
#if BLT_DEBUG_LEVEL > 2
#define BLT_GP_DEBUG_CHECK_TREES
#endif
#ifdef BLT_GP_DEBUG_TRACK_ALLOCATIONS
#undef BLT_GP_DEBUG_TRACK_ALLOCATIONS
#define BLT_GP_DEBUG_TRACK_ALLOCATIONS
#endif
#ifdef BLT_GP_DEBUG_CHECK_TREES
#undef BLT_GP_DEBUG_CHECK_TREES
#define BLT_GP_DEBUG_CHECK_TREES 1
#endif
#endif //BLT_GP_DEFINES_H

View File

@ -23,10 +23,6 @@
#include <blt/logging/logging.h>
#include <blt/std/types.h>
#include <ostream>
#include <cstdlib>
#include <mutex>
#include <atomic>
#include <blt/std/mmap.h>
#include <blt/gp/util/trackers.h>
#include <blt/gp/allocator.h>

View File

@ -46,7 +46,7 @@ namespace blt::gp
void print_args(std::integer_sequence<u64, indices...>)
{
BLT_INFO("Arguments:");
(BLT_INFO("%ld: %s", indices, blt::type_string<Args>().c_str()), ...);
(BLT_INFO("{}: {}", indices, blt::type_string<Args>().c_str()), ...);
}
template <typename Func, u64... indices, typename... ExtraArgs>

View File

@ -374,11 +374,7 @@ namespace blt::gp
{
current_generation = 0;
current_pop = config.pop_initializer.get().generate({
*this,
root_type,
config.population_size,
config.initial_min_tree_size,
config.initial_max_tree_size
*this, root_type, config.population_size, config.initial_min_tree_size, config.initial_max_tree_size
});
next_pop = population_t(current_pop);
BLT_ASSERT_MSG(current_pop.get_individuals().size() == config.population_size,
@ -397,11 +393,7 @@ namespace blt::gp
void generate_initial_population(const type_id root_type)
{
current_pop = config.pop_initializer.get().generate({
*this,
root_type,
config.population_size,
config.initial_min_tree_size,
config.initial_max_tree_size
*this, root_type, config.population_size, config.initial_min_tree_size, config.initial_max_tree_size
});
next_pop = population_t(current_pop);
BLT_ASSERT_MSG(current_pop.get_individuals().size() == config.population_size,

View File

@ -37,53 +37,40 @@ namespace blt::gp
namespace detail
{
BLT_META_MAKE_FUNCTION_CHECK(drop);
// BLT_META_MAKE_FUNCTION_CHECK(drop_ephemeral);
}
/**
* @brief This is the primary class that enables a type-erased GP system without compromising on performance.
*
* This class provides an efficient way to allocate, deallocate, and manage memory blocks
* in a stack-like structure. It supports operations like memory alignment, copying, moving,
* insertion, and removal of memory. This is particularly useful for performance-critical
* systems requiring temporary memory management without frequent heap allocation overhead.
*
* Types placed within this container cannot have an alignment greater than `BLT_GP_MAX_ALIGNMENT` bytes, doing so will result in unaligned pointer access.
* You can configure this by setting `BLT_GP_MAX_ALIGNMENT` as a compiler definition but be aware it will increase memory requirements.
* Setting `BLT_GP_MAX_ALIGNMENT` to lower than 8 is UB on x86-64 systems.
* Consequently, all types have a minimum storage size of `BLT_GP_MAX_ALIGNMENT` (8) bytes, meaning a char, float, int, etc. will take `BLT_GP_MAX_ALIGNMENT` bytes
*/
class stack_allocator
{
constexpr static size_t PAGE_SIZE = 0x100;
template <typename T>
using NO_REF_T = std::remove_cv_t<std::remove_reference_t<T>>;
using Allocator = aligned_allocator;
// todo remove this once i fix all the broken references
struct detail
static constexpr size_t align_bytes(const size_t size) noexcept
{
static constexpr size_t aligned_size(const size_t size) noexcept
{
return (size + (gp::detail::MAX_ALIGNMENT - 1)) & ~(gp::detail::MAX_ALIGNMENT - 1);
return (size + (detail::MAX_ALIGNMENT - 1)) & ~(detail::MAX_ALIGNMENT - 1);
}
};
public:
static Allocator& get_allocator();
struct size_data_t
{
blt::size_t total_size_bytes = 0;
blt::size_t total_used_bytes = 0;
blt::size_t total_remaining_bytes = 0;
friend std::ostream& operator<<(std::ostream& stream, const size_data_t& data)
{
stream << "[";
stream << data.total_used_bytes << " / " << data.total_size_bytes;
stream << " ("
<< (data.total_size_bytes != 0
? (static_cast<double>(data.total_used_bytes) / static_cast<double>(data.total_size_bytes) *
100)
: 0) << "%); space left: " << data.total_remaining_bytes << "]";
return stream;
}
};
template <typename T>
static constexpr size_t aligned_size() noexcept
{
const auto bytes = detail::aligned_size(sizeof(NO_REF_T<T>));
if constexpr (blt::gp::detail::has_func_drop_v<gp::detail::remove_cv_ref<T>>)
return bytes + detail::aligned_size(sizeof(std::atomic_uint64_t*));
const auto bytes = align_bytes(sizeof(std::decay_t<T>));
if constexpr (blt::gp::detail::has_func_drop_v<detail::remove_cv_ref<T>>)
return bytes + align_bytes(sizeof(std::atomic_uint64_t*));
return bytes;
}
@ -166,26 +153,28 @@ namespace blt::gp
std::memcpy(data, data_ + (bytes_stored - bytes), bytes);
}
template <typename T, typename NO_REF = NO_REF_T<T>>
template <typename T>
void push(const T& t)
{
static_assert(std::is_trivially_copyable_v<NO_REF>, "Type must be bitwise copyable!");
static_assert(alignof(NO_REF) <= gp::detail::MAX_ALIGNMENT, "Type alignment must not be greater than the max alignment!");
const auto ptr = static_cast<char*>(allocate_bytes_for_size(aligned_size<NO_REF>()));
std::memcpy(ptr, &t, sizeof(NO_REF));
using DecayedT = std::decay_t<T>;
static_assert(std::is_trivially_copyable_v<DecayedT>, "Type must be bitwise copyable!");
static_assert(alignof(DecayedT) <= detail::MAX_ALIGNMENT, "Type alignment must not be greater than the max alignment!");
const auto ptr = static_cast<char*>(allocate_bytes_for_size(aligned_size<DecayedT>()));
std::memcpy(ptr, &t, sizeof(DecayedT));
if constexpr (gp::detail::has_func_drop_v<gp::detail::remove_cv_ref<T>>)
if constexpr (gp::detail::has_func_drop_v<detail::remove_cv_ref<T>>)
{
new(ptr + sizeof(NO_REF)) mem::pointer_storage<std::atomic_uint64_t>{nullptr};
new(ptr + sizeof(DecayedT)) mem::pointer_storage<std::atomic_uint64_t>{nullptr};
}
}
template <typename T, typename NO_REF = NO_REF_T<T>>
template <typename T>
T pop()
{
static_assert(std::is_trivially_copyable_v<NO_REF>, "Type must be bitwise copyable!");
static_assert(alignof(NO_REF) <= gp::detail::MAX_ALIGNMENT, "Type alignment must not be greater than the max alignment!");
constexpr auto size = aligned_size<NO_REF>();
using DecayedT = std::decay_t<T>;
static_assert(std::is_trivially_copyable_v<DecayedT>, "Type must be bitwise copyable!");
static_assert(alignof(DecayedT) <= detail::MAX_ALIGNMENT, "Type alignment must not be greater than the max alignment!");
constexpr auto size = aligned_size<DecayedT>();
#if BLT_DEBUG_LEVEL > 0
if (bytes_stored < size)
throw std::runtime_error(("Not enough bytes left to pop!" __FILE__ ":") + std::to_string(__LINE__));
@ -205,28 +194,34 @@ namespace blt::gp
return data_ + (bytes_stored - bytes);
}
template <typename T, typename NO_REF = NO_REF_T<T>>
template <typename T>
T& from(const size_t bytes) const
{
static_assert(std::is_trivially_copyable_v<NO_REF> && "Type must be bitwise copyable!");
static_assert(alignof(NO_REF) <= gp::detail::MAX_ALIGNMENT && "Type alignment must not be greater than the max alignment!");
return *reinterpret_cast<NO_REF*>(from(aligned_size<NO_REF>() + bytes));
using DecayedT = std::decay_t<T>;
static_assert(std::is_trivially_copyable_v<DecayedT> && "Type must be bitwise copyable!");
static_assert(alignof(DecayedT) <= detail::MAX_ALIGNMENT && "Type alignment must not be greater than the max alignment!");
return *reinterpret_cast<DecayedT*>(from(aligned_size<DecayedT>() + bytes));
}
[[nodiscard]] std::pair<u8*, mem::pointer_storage<std::atomic_uint64_t>&> access_pointer(const size_t bytes, const size_t type_size) const
{
const auto type_ref = from(bytes);
return {type_ref, *std::launder(
reinterpret_cast<mem::pointer_storage<std::atomic_uint64_t>*>(type_ref + (type_size - detail::aligned_size(
sizeof(std::atomic_uint64_t*)))))};
return {
type_ref, *std::launder(
reinterpret_cast<mem::pointer_storage<std::atomic_uint64_t>*>(type_ref + (type_size - align_bytes(
sizeof(std::atomic_uint64_t*)))))
};
}
[[nodiscard]] std::pair<u8*, mem::pointer_storage<std::atomic_uint64_t>&> access_pointer_forward(const size_t bytes, const size_t type_size) const
[[nodiscard]] std::pair<u8*, mem::pointer_storage<std::atomic_uint64_t>&> access_pointer_forward(
const size_t bytes, const size_t type_size) const
{
const auto type_ref = data_ + bytes;
return {type_ref, *std::launder(
reinterpret_cast<mem::pointer_storage<std::atomic_uint64_t>*>(type_ref + (type_size - detail::aligned_size(
sizeof(std::atomic_uint64_t*)))))};
return {
type_ref, *std::launder(
reinterpret_cast<mem::pointer_storage<std::atomic_uint64_t>*>(type_ref + (type_size - align_bytes(
sizeof(std::atomic_uint64_t*)))))
};
}
template <typename T>
@ -236,7 +231,7 @@ namespace blt::gp
return {
type_ref, *std::launder(
reinterpret_cast<mem::pointer_storage<std::atomic_uint64_t>*>(reinterpret_cast<char*>(&type_ref) +
detail::aligned_size(sizeof(T))))
align_bytes(sizeof(T))))
};
}
@ -264,41 +259,19 @@ namespace blt::gp
pop_bytes(aligned_bytes);
}
// template <typename... Args>
// void call_destructors()
// {
// if constexpr (sizeof...(Args) > 0)
// {
// size_t offset = (aligned_size<NO_REF_T<Args>>() + ...) - aligned_size<NO_REF_T<typename meta::arg_helper<Args...>::First>>();
// ((call_drop<Args>(offset + (gp::detail::has_func_drop_v<Args> ? sizeof(u64*) : 0)), offset -= aligned_size<NO_REF_T<Args>>()), ...);
// (void) offset;
// }
// }
[[nodiscard]] bool empty() const noexcept
{
return bytes_stored == 0;
}
[[nodiscard]] ptrdiff_t remaining_bytes_in_block() const noexcept
[[nodiscard]] ptrdiff_t remainder() const noexcept
{
return static_cast<ptrdiff_t>(size_ - bytes_stored);
}
[[nodiscard]] ptrdiff_t bytes_in_head() const noexcept
[[nodiscard]] size_t stored() const noexcept
{
return static_cast<ptrdiff_t>(bytes_stored);
}
[[nodiscard]] size_data_t size() const noexcept
{
size_data_t data;
data.total_used_bytes = bytes_stored;
data.total_size_bytes = size_;
data.total_remaining_bytes = remaining_bytes_in_block();
return data;
return bytes_stored;
}
void reserve(const size_t bytes)
@ -307,12 +280,13 @@ namespace blt::gp
expand_raw(bytes);
}
[[nodiscard]] size_t stored() const
void resize(const size_t bytes)
{
return bytes_stored;
reserve(bytes);
bytes_stored = bytes;
}
[[nodiscard]] size_t internal_storage_size() const
[[nodiscard]] size_t capacity() const
{
return size_;
}
@ -322,6 +296,11 @@ namespace blt::gp
bytes_stored = 0;
}
[[nodiscard]] auto* data() const
{
return data_;
}
private:
void expand(const size_t bytes)
{
@ -350,7 +329,7 @@ namespace blt::gp
{
if (data_ == nullptr)
return nullptr;
size_t remaining_bytes = remaining_bytes_in_block();
size_t remaining_bytes = remainder();
auto* pointer = static_cast<void*>(data_ + bytes_stored);
return std::align(gp::detail::MAX_ALIGNMENT, bytes, pointer, remaining_bytes);
}
@ -372,15 +351,6 @@ namespace blt::gp
return aligned_ptr;
}
// template <typename T>
// void call_drop(const size_t offset)
// {
// if constexpr (blt::gp::detail::has_func_drop_v<T>)
// {
// from<NO_REF_T<T>>(offset).drop();
// }
// }
u8* data_ = nullptr;
// place in the data_ array which has a free spot.
size_t bytes_stored = 0;

88
include/blt/gp/sync.h Normal file
View File

@ -0,0 +1,88 @@
#pragma once
/*
* Copyright (C) 2024 Brett Terpstra
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef BLT_GP_SYNC_H
#define BLT_GP_SYNC_H
#include <blt/std/types.h>
#include <blt/gp/fwdecl.h>
namespace blt::gp
{
class sync_t
{
public:
explicit sync_t(gp_program& program, fs::writer_t& writer);
virtual void trigger(u64 current_time) const;
sync_t& with_timer(u64 seconds)
{
m_timer_seconds = seconds;
return *this;
}
sync_t& every_generations(u64 generations)
{
m_generations = generations;
return *this;
}
sync_t& overwrite_file_on_write()
{
m_reset_to_start_of_file = true;
return *this;
}
sync_t& append_to_file_on_write()
{
m_reset_to_start_of_file = false;
return *this;
}
/**
* Save the state of the whole program instead of just the generation information.
*/
sync_t& whole_program()
{
m_whole_program = true;
return *this;
}
/**
* Only save the current generation to disk.
*/
sync_t& generation_only()
{
m_whole_program = false;
return *this;
}
~sync_t();
private:
gp_program* m_program;
fs::writer_t* m_writer;
std::optional<u64> m_timer_seconds;
std::optional<u64> m_generations;
bool m_reset_to_start_of_file = false;
bool m_whole_program = false;
};
}
#endif //BLT_GP_SYNC_H

View File

@ -97,9 +97,9 @@ namespace blt::gp
task_builder_t() = default;
template <typename... Tasks>
static std::function<void(barrier&, EnumId, size_t)> make_callable(Tasks&&... tasks)
static std::function<void(barrier_t&, EnumId, size_t)> make_callable(Tasks&&... tasks)
{
return [&tasks...](barrier& sync_barrier, EnumId task, size_t thread_index)
return [&tasks...](barrier_t& sync_barrier, EnumId task, size_t thread_index)
{
call_jmp_table(sync_barrier, task, thread_index, tasks...);
};
@ -107,7 +107,7 @@ namespace blt::gp
private:
template <typename Task>
static void execute(barrier& sync_barrier, const size_t thread_index, Task&& task)
static void execute(barrier_t& sync_barrier, const size_t thread_index, Task&& task)
{
// sync_barrier.wait();
if (task.requires_single_sync)
@ -121,7 +121,7 @@ namespace blt::gp
}
template <typename Task>
static bool call(barrier& sync_barrier, const EnumId current_task, const size_t thread_index, Task&& task)
static bool call(barrier_t& sync_barrier, const EnumId current_task, const size_t thread_index, Task&& task)
{
if (static_cast<EnumInt>(current_task) == static_cast<EnumInt>(task.get_task_id()))
{
@ -132,7 +132,7 @@ namespace blt::gp
}
template <typename... Tasks>
static void call_jmp_table(barrier& sync_barrier, const EnumId current_task, const size_t thread_index, Tasks&&... tasks)
static void call_jmp_table(barrier_t& sync_barrier, const EnumId current_task, const size_t thread_index, Tasks&&... tasks)
{
if (static_cast<EnumInt>(current_task) >= sizeof...(tasks))
BLT_UNREACHABLE;
@ -146,7 +146,7 @@ namespace blt::gp
static_assert(std::is_enum_v<EnumId>, "Enum ID must be of enum type!");
public:
explicit thread_manager_t(const size_t thread_count, std::function<void(barrier&, EnumId, size_t)> task_func,
explicit thread_manager_t(const size_t thread_count, std::function<void(barrier_t&, EnumId, size_t)> task_func,
const bool will_main_block = true): barrier(thread_count), will_main_block(will_main_block)
{
thread_callable = [this, task_func = std::move(task_func)](const size_t thread_index)
@ -226,7 +226,7 @@ namespace blt::gp
return will_main_block ? threads.size() + 1 : threads.size();
}
blt::barrier barrier;
blt::barrier_t barrier;
std::atomic_bool should_run = true;
bool will_main_block;
std::vector<EnumId> tasks;

View File

@ -64,12 +64,6 @@ namespace blt::gp
operator_info_t& type_operator_info;
};
struct crossover_point_t
{
tree_t::subtree_point_t p1_crossover_point;
tree_t::subtree_point_t p2_crossover_point;
};
struct config_t
{
// number of times crossover will try to pick a valid point in the tree. this is purely based on the return type of the operators
@ -88,22 +82,60 @@ namespace blt::gp
f32 terminal_chance = 0.1;
// use traversal to select point instead of random selection
bool traverse = false;
};
crossover_t() = default;
BLT_MAKE_SETTER_LVALUE(u32, max_crossover_tries);
BLT_MAKE_SETTER_LVALUE(u32, max_crossover_iterations);
BLT_MAKE_SETTER_LVALUE(u32, min_tree_size);
BLT_MAKE_SETTER_LVALUE(f32, depth_multiplier);
BLT_MAKE_SETTER_LVALUE(f32, terminal_chance);
BLT_MAKE_SETTER_LVALUE(bool, traverse);
};
explicit crossover_t(const config_t& config): config(config)
{
}
/**
* Apply crossover to a set of parents. Note: c1 and c2 are already filled with thier respective parent's elements.
* @return true if the crossover succeeded, otherwise return false will erase progress.
*/
virtual bool apply(gp_program& program, const tree_t& p1, const tree_t& p2, tree_t& c1, tree_t& c2) = 0;
[[nodiscard]] const config_t& get_config() const
{
return config;
}
std::optional<crossover_point_t> get_crossover_point(const tree_t& c1, const tree_t& c2) const;
virtual ~crossover_t() = default;
std::optional<crossover_point_t> get_crossover_point_traverse(const tree_t& c1, const tree_t& c2) const;
protected:
config_t config;
};
/**
* Base class for crossover which performs basic subtree crossover on two random nodes in the parent tree
*/
class subtree_crossover_t : public crossover_t
{
public:
struct crossover_point_t
{
tree_t::subtree_point_t p1_crossover_point;
tree_t::subtree_point_t p2_crossover_point;
};
subtree_crossover_t(): crossover_t(config_t{})
{
}
explicit subtree_crossover_t(const config_t& config): crossover_t(config)
{
}
[[nodiscard]] std::optional<crossover_point_t> get_crossover_point(const tree_t& c1, const tree_t& c2) const;
[[nodiscard]] std::optional<crossover_point_t> get_crossover_point_traverse(const tree_t& c1, const tree_t& c2) const;
/**
* child1 and child2 are copies of the parents, the result of selecting a crossover point and performing standard subtree crossover.
@ -111,16 +143,39 @@ namespace blt::gp
* @param program reference to the global program container responsible for managing these trees
* @param p1 reference to the first parent
* @param p2 reference to the second parent
* @return expected pair of child otherwise returns error enum
* @param c1 reference to output child 1
* @param c2 reference to output child 2
* @return true if function succeeded, otherwise false
*/
virtual bool apply(gp_program& program, const tree_t& p1, const tree_t& p2, tree_t& c1, tree_t& c2); // NOLINT
virtual bool apply(gp_program& program, const tree_t& p1, const tree_t& p2, tree_t& c1, tree_t& c2) override; // NOLINT
virtual ~crossover_t() = default;
~subtree_crossover_t() override = default;
protected:
[[nodiscard]] std::optional<tree_t::subtree_point_t> get_point_traverse_retry(const tree_t& t, std::optional<type_id> type) const;
};
config_t config;
class one_point_crossover_t : public crossover_t
{
public:
one_point_crossover_t(): crossover_t(config_t{})
{
}
explicit one_point_crossover_t(const config_t& config): crossover_t(config)
{
}
bool apply(gp_program& program, const tree_t& p1, const tree_t& p2, tree_t& c1, tree_t& c2) override;
};
class advanced_crossover_t : public crossover_t
{
advanced_crossover_t(): crossover_t(config_t{})
{
}
public:
bool apply(gp_program& program, const tree_t& p1, const tree_t& p2, tree_t& c1, tree_t& c2) override;
};
class mutation_t

View File

@ -24,6 +24,7 @@
#include <blt/gp/stack.h>
#include <blt/gp/fwdecl.h>
#include <blt/std/types.h>
#include <blt/fs/fwddecl.h>
#include <utility>
#include <stack>
@ -87,6 +88,8 @@ namespace blt::gp
return m_flags;
}
friend bool operator==(const op_container_t& a, const op_container_t& b);
private:
size_t m_type_size;
operator_id m_id;
@ -185,18 +188,13 @@ namespace blt::gp
class tree_t
{
public:
struct child_t
{
ptrdiff_t start;
// one past the end
ptrdiff_t end;
};
struct subtree_point_t
{
ptrdiff_t pos;
type_id type;
subtree_point_t() = default;
explicit subtree_point_t(const ptrdiff_t pos): pos(pos), type(0)
{
}
@ -206,6 +204,15 @@ namespace blt::gp
}
};
struct child_t
{
ptrdiff_t start;
// one past the end
ptrdiff_t end;
};
struct byte_only_transaction_t
{
byte_only_transaction_t(tree_t& tree, const size_t bytes): tree(tree), data(nullptr), bytes(bytes)
@ -411,6 +418,13 @@ namespace blt::gp
copy_subtree(point, find_endpoint(point.pos), out_tree);
}
void copy_subtree(const child_t subtree, tree_t& out_tree)
{
copy_subtree(subtree_point_t{subtree.start}, subtree.end, out_tree);
}
void swap_subtrees(child_t our_subtree, tree_t& other_tree, child_t other_subtree);
/**
* Swaps the subtrees between this tree and the other tree
* @param our_subtree
@ -457,6 +471,11 @@ namespace blt::gp
delete_subtree(point, find_endpoint(point.pos));
}
void delete_subtree(const child_t subtree)
{
delete_subtree(subtree_point_t{subtree.start}, subtree.end);
}
/**
* Insert a subtree before the specified point
* @param point point to insert into
@ -583,7 +602,8 @@ namespace blt::gp
template <typename Context, typename... Operators>
static auto make_execution_lambda(size_t call_reserve_size, Operators&... operators)
{
return [call_reserve_size, &operators...](const tree_t& tree, void* context) -> evaluation_context& {
return [call_reserve_size, &operators...](const tree_t& tree, void* context) -> evaluation_context&
{
const auto& ops = tree.operations;
const auto& vals = tree.values;
@ -608,6 +628,16 @@ namespace blt::gp
};
}
[[nodiscard]] size_t required_size() const;
void to_byte_array(std::byte* out) const;
void to_file(fs::writer_t& file) const;
void from_byte_array(const std::byte* in);
void from_file(fs::reader_t& file);
~tree_t()
{
clear(*m_program);
@ -615,6 +645,13 @@ namespace blt::gp
static tree_t& get_thread_local(gp_program& program);
friend bool operator==(const tree_t& a, const tree_t& b);
friend bool operator!=(const tree_t& a, const tree_t& b)
{
return !(a == b);
}
private:
void handle_operator_inserted(const op_container_t& op);
@ -766,6 +803,13 @@ namespace blt::gp
individual_t& operator=(const individual_t&) = delete;
individual_t& operator=(individual_t&&) = default;
friend bool operator==(const individual_t& a, const individual_t& b);
friend bool operator!=(const individual_t& a, const individual_t& b)
{
return !(a == b);
}
};
class population_t

View File

@ -196,6 +196,20 @@ namespace blt::gp
worst_fitness = std::numeric_limits<double>::max();
normalized_fitness.clear();
}
friend bool operator==(const population_stats& a, const population_stats& b)
{
return a.overall_fitness.load(std::memory_order_relaxed) == b.overall_fitness.load(std::memory_order_relaxed) &&
a.average_fitness.load(std::memory_order_relaxed) == b.average_fitness.load(std::memory_order_relaxed) &&
a.best_fitness.load(std::memory_order_relaxed) == b.best_fitness.load(std::memory_order_relaxed) &&
a.worst_fitness.load(std::memory_order_relaxed) == b.worst_fitness.load(std::memory_order_relaxed) &&
a.normalized_fitness == b.normalized_fitness;
}
friend bool operator!=(const population_stats& a, const population_stats& b)
{
return !(a == b);
}
};
}

View File

@ -17,6 +17,13 @@
*/
#include <blt/gp/program.h>
#include <iostream>
#include <blt/std/variant.h>
#ifndef BLT_ASSERT_RET
#define BLT_ASSERT_RET(expr) if (!(expr)) { return false; }
#endif
#define BLT_READ(read_statement, size) do { auto read = read_statement; if (read != size) { return blt::gp::errors::serialization::invalid_read_t{read, size}; } } while (false)
namespace blt::gp
{
@ -24,25 +31,28 @@ namespace blt::gp
// this is largely to not break the tests :3
// it's also to allow for quick setup of a gp program if you don't care how crossover or mutation is handled
static advanced_mutation_t s_mutator;
static crossover_t s_crossover;
static subtree_crossover_t s_crossover;
// static one_point_crossover_t s_crossover;
static ramped_half_initializer_t s_init;
prog_config_t::prog_config_t(): mutator(s_mutator), crossover(s_crossover), pop_initializer(s_init)
{
}
prog_config_t::prog_config_t(const std::reference_wrapper<population_initializer_t>& popInitializer):
mutator(s_mutator), crossover(s_crossover), pop_initializer(popInitializer)
{}
{
}
prog_config_t::prog_config_t(size_t populationSize, const std::reference_wrapper<population_initializer_t>& popInitializer):
population_size(populationSize), mutator(s_mutator), crossover(s_crossover), pop_initializer(popInitializer)
{}
{
}
prog_config_t::prog_config_t(size_t populationSize):
population_size(populationSize), mutator(s_mutator), crossover(s_crossover), pop_initializer(s_init)
{}
{
}
random_t& gp_program::get_random() const
{
@ -56,6 +66,171 @@ namespace blt::gp
return allocator;
}
void gp_program::save_generation(fs::writer_t& writer)
{
const auto individuals = current_pop.get_individuals().size();
writer.write(&individuals, sizeof(individuals));
for (const auto& individual : current_pop.get_individuals())
{
writer.write(&individual.fitness, sizeof(individual.fitness));
individual.tree.to_file(writer);
}
}
bool gp_program::load_generation(fs::reader_t& reader)
{
size_t individuals;
BLT_ASSERT_RET(reader.read(&individuals, sizeof(individuals)) == sizeof(individuals));
if (current_pop.get_individuals().size() != individuals)
{
for (size_t i = current_pop.get_individuals().size(); i < individuals; i++)
current_pop.get_individuals().emplace_back(tree_t{*this});
}
for (auto& individual : current_pop.get_individuals())
{
BLT_ASSERT_RET(reader.read(&individual.fitness, sizeof(individual.fitness)) == sizeof(individual.fitness));
individual.tree.clear(*this);
individual.tree.from_file(reader);
}
return true;
}
void write_stat(fs::writer_t& writer, const population_stats& stat)
{
const auto overall_fitness = stat.overall_fitness.load();
const auto average_fitness = stat.average_fitness.load();
const auto best_fitness = stat.best_fitness.load();
const auto worst_fitness = stat.worst_fitness.load();
writer.write(&overall_fitness, sizeof(overall_fitness));
writer.write(&average_fitness, sizeof(average_fitness));
writer.write(&best_fitness, sizeof(best_fitness));
writer.write(&worst_fitness, sizeof(worst_fitness));
const size_t fitness_count = stat.normalized_fitness.size();
writer.write(&fitness_count, sizeof(fitness_count));
for (const auto& fitness : stat.normalized_fitness)
writer.write(&fitness, sizeof(fitness));
}
bool load_stat(fs::reader_t& reader, population_stats& stat)
{
BLT_ASSERT_RET(reader.read(&stat.overall_fitness, sizeof(stat.overall_fitness)) == sizeof(stat.overall_fitness));
BLT_ASSERT_RET(reader.read(&stat.average_fitness, sizeof(stat.average_fitness)) == sizeof(stat.average_fitness));
BLT_ASSERT_RET(reader.read(&stat.best_fitness, sizeof(stat.best_fitness)) == sizeof(stat.best_fitness));
BLT_ASSERT_RET(reader.read(&stat.worst_fitness, sizeof(stat.worst_fitness)) == sizeof(stat.worst_fitness));
size_t fitness_count;
BLT_ASSERT_RET(reader.read(&fitness_count, sizeof(fitness_count)) == sizeof(size_t));
stat.normalized_fitness.resize(fitness_count);
for (auto& fitness : stat.normalized_fitness)
BLT_ASSERT_RET(reader.read(&fitness, sizeof(fitness)) == sizeof(fitness));
return true;
}
void gp_program::save_state(fs::writer_t& writer)
{
const size_t operator_count = storage.operators.size();
writer.write(&operator_count, sizeof(operator_count));
for (const auto& [i, op] : enumerate(storage.operators))
{
writer.write(&i, sizeof(i));
bool has_name = storage.names[i].has_value();
writer.write(&has_name, sizeof(has_name));
if (has_name)
{
auto size = storage.names[i]->size();
writer.write(&size, sizeof(size));
writer.write(storage.names[i]->data(), size);
}
writer.write(&storage.operator_metadata[i].arg_size_bytes, sizeof(storage.operator_metadata[i].arg_size_bytes));
writer.write(&storage.operator_metadata[i].return_size_bytes, sizeof(storage.operator_metadata[i].return_size_bytes));
writer.write(&op.argc, sizeof(op.argc));
writer.write(&op.return_type, sizeof(op.return_type));
const size_t argc_type_count = op.argument_types.size();
writer.write(&argc_type_count, sizeof(argc_type_count));
for (const auto argument : op.argument_types)
writer.write(&argument, sizeof(argument));
}
const size_t history_count = statistic_history.size();
writer.write(&history_count, sizeof(history_count));
for (const auto& stat : statistic_history)
write_stat(writer, stat);
write_stat(writer, current_stats);
save_generation(writer);
}
std::optional<errors::serialization::serializer_error_t> gp_program::load_state(fs::reader_t& reader)
{
size_t operator_count;
BLT_READ(reader.read(&operator_count, sizeof(operator_count)), sizeof(operator_count));
if (operator_count != storage.operators.size())
return errors::serialization::unexpected_size_t{operator_count, storage.operators.size()};
for (size_t i = 0; i < operator_count; i++)
{
size_t expected_i;
BLT_READ(reader.read(&expected_i, sizeof(expected_i)), sizeof(expected_i));
if (expected_i != i)
return errors::serialization::invalid_operator_id_t{i, expected_i};
bool has_name;
BLT_READ(reader.read(&has_name, sizeof(has_name)), sizeof(has_name));
if (has_name)
{
size_t size;
BLT_READ(reader.read(&size, sizeof(size)), sizeof(size));
std::string name;
name.resize(size);
BLT_READ(reader.read(name.data(), size), static_cast<i64>(size));
if (!storage.names[i].has_value())
return errors::serialization::invalid_name_t{i, name, "NO NAME"};
if (name != *storage.names[i])
return errors::serialization::invalid_name_t{i, name, std::string{*storage.names[i]}};
const auto& op = storage.operators[i];
const auto& op_meta = storage.operator_metadata[i];
decltype(std::declval<decltype(storage.operator_metadata)::value_type>().arg_size_bytes) arg_size_bytes;
decltype(std::declval<decltype(storage.operator_metadata)::value_type>().return_size_bytes) return_size_bytes;
BLT_READ(reader.read(&arg_size_bytes, sizeof(arg_size_bytes)), sizeof(arg_size_bytes));
BLT_READ(reader.read(&return_size_bytes, sizeof(return_size_bytes)), sizeof(return_size_bytes));
if (op_meta.arg_size_bytes != arg_size_bytes)
return errors::serialization::mismatched_bytes_t{i, arg_size_bytes, op_meta.arg_size_bytes};
if (op_meta.return_size_bytes != return_size_bytes)
return errors::serialization::mismatched_bytes_t{i, return_size_bytes, op_meta.return_size_bytes};
argc_t argc;
BLT_READ(reader.read(&argc, sizeof(argc)), sizeof(argc));
if (argc.argc != op.argc.argc)
return errors::serialization::mismatched_argc_t{i, argc.argc, op.argc.argc};
if (argc.argc_context != op.argc.argc_context)
return errors::serialization::mismatched_argc_t{i, argc.argc_context, op.argc.argc_context};
type_id return_type;
BLT_READ(reader.read(&return_type, sizeof(return_type)), sizeof(return_type));
if (return_type != op.return_type)
return errors::serialization::mismatched_return_type_t{i, return_type, op.return_type};
size_t arg_type_count;
BLT_READ(reader.read(&arg_type_count, sizeof(arg_type_count)), sizeof(return_type));
if (arg_type_count != op.argument_types.size())
return errors::serialization::unexpected_size_t{arg_type_count, op.argument_types.size()};
for (size_t j = 0; j < arg_type_count; j++)
{
type_id type;
BLT_READ(reader.read(&type, sizeof(type)), sizeof(type));
if (type != op.argument_types[j])
return errors::serialization::mismatched_arg_type_t{i, j, type, op.argument_types[j]};
}
}
}
size_t history_count;
BLT_READ(reader.read(&history_count, sizeof(history_count)), sizeof(history_count));
statistic_history.resize(history_count);
for (size_t i = 0; i < history_count; i++)
load_stat(reader, statistic_history[i]);
load_stat(reader, current_stats);
load_generation(reader);
return {};
}
void gp_program::create_threads()
{
#ifdef BLT_TRACK_ALLOCATIONS
@ -67,7 +242,8 @@ namespace blt::gp
// main thread is thread0
for (blt::size_t i = 1; i < config.threads; i++)
{
thread_helper.threads.emplace_back(new std::thread([i, this]() {
thread_helper.threads.emplace_back(new std::thread([i, this]()
{
#ifdef BLT_TRACK_ALLOCATIONS
tracker.reserve();
tracker.await_thread_loading_complete(config.threads);

106
src/sync.cpp Normal file
View File

@ -0,0 +1,106 @@
/*
* <Short Description>
* Copyright (C) 2025 Brett Terpstra
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <blt/gp/sync.h>
#include <thread>
#include <atomic>
#include <blt/gp/program.h>
#include <blt/std/time.h>
namespace blt::gp
{
struct global_sync_state_t
{
std::vector<sync_t*> syncs;
std::mutex mutex;
std::thread* thread = nullptr;
std::atomic_bool should_run = true;
std::condition_variable condition_variable;
void add(sync_t* sync)
{
if (thread == nullptr)
{
thread = new std::thread([this]()
{
while (should_run)
{
std::unique_lock lock(mutex);
condition_variable.wait_for(lock, std::chrono::milliseconds(100));
const auto current_time = system::getCurrentTimeMilliseconds();
for (const auto& sync : syncs)
sync->trigger(current_time);
}
});
}
std::scoped_lock lock(mutex);
syncs.push_back(sync);
}
void remove(const sync_t* sync)
{
if (thread == nullptr)
{
BLT_WARN("Tried to remove sync from global sync state, but no thread was running");
return;
}
std::unique_lock lock(mutex);
const auto iter = std::find(syncs.begin(), syncs.end(), sync);
std::iter_swap(iter, syncs.end() - 1);
syncs.pop_back();
if (syncs.empty())
{
lock.unlock();
should_run = false;
condition_variable.notify_all();
thread->join();
delete thread;
thread = nullptr;
}
}
};
global_sync_state_t& get_state()
{
static global_sync_state_t state;
return state;
}
sync_t::sync_t(gp_program& program, fs::writer_t& writer): m_program(&program), m_writer(&writer)
{
get_state().add(this);
}
void sync_t::trigger(const u64 current_time) const
{
if ((m_timer_seconds && (current_time % *m_timer_seconds == 0)) || (m_generations && (m_program->get_current_generation() % *m_generations ==
0)))
{
if (m_reset_to_start_of_file)
m_writer->seek(0, fs::writer_t::seek_origin::seek_set);
if (m_whole_program)
m_program->save_state(*m_writer);
else
m_program->save_generation(*m_writer);
}
}
sync_t::~sync_t()
{
get_state().remove(this);
}
}

View File

@ -65,7 +65,7 @@ namespace blt::gp
{
}
bool crossover_t::apply(gp_program& program, const tree_t& p1, const tree_t& p2, tree_t& c1, tree_t& c2) // NOLINT
bool subtree_crossover_t::apply(gp_program& program, const tree_t& p1, const tree_t& p2, tree_t& c1, tree_t& c2) // NOLINT
{
if (p1.size() < config.min_tree_size || p2.size() < config.min_tree_size)
return false;
@ -80,13 +80,318 @@ namespace blt::gp
if (!point)
return false;
c1.swap_subtrees(point->p1_crossover_point, c2, point->p2_crossover_point);
#if BLT_DEBUG_LEVEL >= 2
if (!c1.check(detail::debug::context_ptr) || !c2.check(detail::debug::context_ptr))
throw std::runtime_error("Tree check failed");
#endif
return true;
}
std::optional<subtree_crossover_t::crossover_point_t> subtree_crossover_t::get_crossover_point(const tree_t& c1,
const tree_t& c2) const
{
const auto first = c1.select_subtree(config.terminal_chance);
const auto second = c2.select_subtree(first.type, config.max_crossover_tries, config.terminal_chance);
if (!second)
return {};
return {{first, *second}};
}
std::optional<subtree_crossover_t::crossover_point_t> subtree_crossover_t::get_crossover_point_traverse(const tree_t& c1,
const tree_t& c2) const
{
auto c1_point_o = get_point_traverse_retry(c1, {});
if (!c1_point_o)
return {};
const auto c2_point_o = get_point_traverse_retry(c2, c1_point_o->type);
if (!c2_point_o)
return {};
return {{*c1_point_o, *c2_point_o}};
}
std::optional<tree_t::subtree_point_t> subtree_crossover_t::get_point_traverse_retry(const tree_t& t, const std::optional<type_id> type) const
{
if (type)
return t.select_subtree_traverse(*type, config.max_crossover_tries, config.terminal_chance, config.depth_multiplier);
return t.select_subtree_traverse(config.terminal_chance, config.depth_multiplier);
}
bool one_point_crossover_t::apply(gp_program& program, const tree_t& p1, const tree_t& p2, tree_t& c1, tree_t& c2)
{
// if (p1.size() < config.min_tree_size || p2.size() < config.min_tree_size)
// return false;
tree_t::subtree_point_t point1, point2; // NOLINT
if (config.traverse)
{
point1 = p1.select_subtree_traverse(config.terminal_chance, config.depth_multiplier);
if (const auto val = p2.select_subtree_traverse(point1.type, config.max_crossover_tries, config.terminal_chance, config.depth_multiplier))
point2 = *val;
else
return false;
} else
{
point1 = p1.select_subtree(config.terminal_chance);
if (const auto val = p2.select_subtree(point1.type, config.max_crossover_tries, config.terminal_chance))
point2 = *val;
else
return false;
}
const auto& p1_operator = p1.get_operator(point1.pos);
const auto& p2_operator = p2.get_operator(point2.pos);
const auto& p1_info = program.get_operator_info(p1_operator.id());
const auto& p2_info = program.get_operator_info(p2_operator.id());
struct reorder_index_t
{
size_t index1;
size_t index2;
};
struct swap_index_t
{
size_t p1_index;
size_t p2_index;
};
thread_local struct type_resolver_t
{
tracked_vector<tree_t::child_t> children_data_p1;
tracked_vector<tree_t::child_t> children_data_p2;
hashmap_t<type_id, std::vector<size_t>> missing_p1_types;
hashmap_t<type_id, std::vector<size_t>> missing_p2_types;
hashset_t<size_t> correct_types;
hashset_t<size_t> p1_correct_types;
hashset_t<size_t> p2_correct_types;
std::vector<reorder_index_t> p1_reorder_types;
std::vector<reorder_index_t> p2_reorder_types;
std::vector<swap_index_t> swap_types;
std::vector<tree_t> temp_trees;
void print_missing_types()
{
for (const auto& [id, v] : missing_p1_types)
{
if (!v.empty())
{
BLT_INFO("(P1) For type {} missing indexes:", id);
for (const auto idx : v)
BLT_INFO("\t{}", idx);
BLT_INFO("----");
}
}
for (const auto& [id, v] : missing_p2_types)
{
if (!v.empty())
{
BLT_INFO("(P2) For type {} missing indexes:", id);
for (const auto idx : v)
BLT_INFO("\t{}", idx);
BLT_INFO("----");
}
}
}
std::optional<size_t> get_p1_index(const type_id& id)
{
if (!missing_p1_types.contains(id))
return {};
if (missing_p1_types[id].empty())
return {};
auto idx = missing_p1_types[id].back();
missing_p1_types[id].pop_back();
return idx;
}
std::optional<size_t> get_p2_index(const type_id& id)
{
if (!missing_p2_types.contains(id))
return {};
if (missing_p2_types[id].empty())
return {};
auto idx = missing_p2_types[id].back();
missing_p2_types[id].pop_back();
return idx;
}
[[nodiscard]] bool handled_p1(const size_t index) const
{
return correct_types.contains(index) || p1_correct_types.contains(index);
}
[[nodiscard]] bool handled_p2(const size_t index) const
{
return correct_types.contains(index) || p2_correct_types.contains(index);
}
void clear(gp_program& program)
{
children_data_p1.clear();
children_data_p2.clear();
correct_types.clear();
p1_correct_types.clear();
p2_correct_types.clear();
p1_reorder_types.clear();
p2_reorder_types.clear();
swap_types.clear();
for (auto& tree : temp_trees)
tree.clear(program);
for (auto& [id, v] : missing_p1_types)
v.clear();
for (auto& [id, v] : missing_p2_types)
v.clear();
}
} resolver;
resolver.clear(program);
auto min_size = std::min(p1_info.argument_types.size(), p2_info.argument_types.size());
// resolve type information
for (size_t i = 0; i < min_size; i++)
{
if (p1_info.argument_types[i] != p2_info.argument_types[i])
{
resolver.missing_p1_types[p1_info.argument_types[i].id].push_back(i);
resolver.missing_p2_types[p2_info.argument_types[i].id].push_back(i);
} else
resolver.correct_types.insert(i);
}
for (size_t i = min_size; i < p1_info.argument_types.size(); i++)
resolver.missing_p1_types[p1_info.argument_types[i].id].push_back(i);
for (size_t i = min_size; i < p2_info.argument_types.size(); i++)
resolver.missing_p2_types[p2_info.argument_types[i].id].push_back(i);
// if swaping p1 -> p2 and p2 -> p1, we may already have the types we need just in a different order
// first, make a list of types which can simply be reordered
for (size_t i = 0; i < p1_info.argument_types.size(); i++)
{
if (resolver.correct_types.contains(i))
continue;
if (auto index = resolver.get_p2_index(p1_info.argument_types[i].id))
{
resolver.p2_reorder_types.push_back({i, *index});
resolver.p2_correct_types.insert(i);
}
}
BLT_DEBUG("Operator C1 {} expects types: ", p1_operator.id());
for (const auto [i, type] : enumerate(p1_info.argument_types))
BLT_TRACE("{} -> {}", i, type);
BLT_DEBUG("Operator C2 {} expects types: ", p2_operator.id());
for (const auto [i, type] : enumerate(p2_info.argument_types))
BLT_TRACE("{} -> {}", i, type);
resolver.print_missing_types();
for (size_t i = 0; i < p2_info.argument_types.size(); i++)
{
if (resolver.correct_types.contains(i))
continue;
if (auto index = resolver.get_p1_index(p2_info.argument_types[i].id))
{
resolver.p1_reorder_types.push_back({i, *index});
resolver.p1_correct_types.insert(i);
}
}
// next we need to figure out which types need to be swapped
for (size_t i = 0; i < p1_info.argument_types.size(); i++)
{
if (resolver.handled_p2(i))
continue;
if (auto index = resolver.get_p1_index(p1_info.argument_types[i].id))
resolver.swap_types.push_back({*index, i});
}
for (size_t i = 0; i < p2_info.argument_types.size(); i++)
{
if (resolver.handled_p1(i))
continue;
if (auto index = resolver.get_p2_index(p2_info.argument_types[i].id))
resolver.swap_types.push_back({i, *index});
}
// now we do the swap
p1.find_child_extends(resolver.children_data_p1, point1.pos, p1_info.argument_types.size());
p2.find_child_extends(resolver.children_data_p2, point2.pos, p2_info.argument_types.size());
for (const auto& [index1, index2] : resolver.p1_reorder_types)
{
BLT_DEBUG("Reordering in C1: {} -> {}", index1, index2);
c1.swap_subtrees(resolver.children_data_p1[index1], c1, resolver.children_data_p1[index2]);
}
for (const auto& [index1, index2] : resolver.p2_reorder_types)
{
BLT_DEBUG("Reordering in C2: {} -> {}", index1, index2);
c2.swap_subtrees(resolver.children_data_p2[index1], c2, resolver.children_data_p2[index2]);
}
auto c1_insert = resolver.children_data_p1.back().end;
auto c2_insert = resolver.children_data_p2.back().end;
for (const auto& [p1_index, p2_index] : resolver.swap_types)
{
if (p1_index < p1_info.argument_types.size() && p2_index < p2_info.argument_types.size())
c1.swap_subtrees(resolver.children_data_p1[p1_index], c2, resolver.children_data_p2[p2_index]);
else if (p1_index < p1_info.argument_types.size() && p2_index >= p2_info.argument_types.size())
{
BLT_TRACE("(P1 IS UNDER!) Trying to swap P1 {} for P2 {} (Sizes: P1: {} P2: {})", p1_index, p2_index, p1_info.argument_types.size(), p2_info.argument_types.size());
BLT_TRACE("Inserting into P2 from P1!");
c1.copy_subtree(resolver.children_data_p1[p1_index], resolver.temp_trees[0]);
c1.delete_subtree(resolver.children_data_p1[p1_index]);
c2_insert = c2.insert_subtree(tree_t::subtree_point_t{c1_insert}, resolver.temp_trees[0]);
} else if (p2_index < p2_info.argument_types.size() && p1_index >= p1_info.argument_types.size())
{
BLT_TRACE("(P2 IS UNDER!) Trying to swap P1 {} for P2 {} (Sizes: P1: {} P2: {})", p1_index, p2_index, p1_info.argument_types.size(), p2_info.argument_types.size());
} else
{
BLT_WARN("This should be an impossible state!");
}
}
c1.modify_operator(point1.pos, p2_operator.id(), p2_info.return_type);
c2.modify_operator(point2.pos, p1_operator.id(), p1_info.return_type);
#if BLT_DEBUG_LEVEL >= 2
if (!c1.check(detail::debug::context_ptr) || !c2.check(detail::debug::context_ptr))
throw std::runtime_error("Tree check failed");
#endif
return true;
}
bool advanced_crossover_t::apply(gp_program& program, const tree_t& p1, const tree_t& p2, tree_t& c1, tree_t& c2)
{
if (p1.size() < config.min_tree_size || p2.size() < config.min_tree_size)
return false;
// TODO: more crossover!
switch (program.get_random().get_u32(0, 2))
{
// single point crossover (only if operators at this point are "compatible")
case 0:
{
// check if can work
// otherwise goto case2
}
// Mating crossover analogs to same species breeding. Only works if tree is mostly similar
case 1:
c1.swap_subtrees(point->p1_crossover_point, c2, point->p2_crossover_point);
break;
{
}
// Subtree crossover, select random points inside trees and swap their subtrees
case 2:
return subtree_crossover_t{}.apply(program, p1, p2, c1, c2);
default:
#if BLT_DEBUG_LEVEL > 0
BLT_ABORT("This place should be unreachable!");
@ -99,39 +404,6 @@ namespace blt::gp
if (!c1.check(detail::debug::context_ptr) || !c2.check(detail::debug::context_ptr))
throw std::runtime_error("Tree check failed");
#endif
return true;
}
std::optional<crossover_t::crossover_point_t> crossover_t::get_crossover_point(const tree_t& c1,
const tree_t& c2) const
{
auto first = c1.select_subtree(config.terminal_chance);
auto second = c2.select_subtree(first.type, config.max_crossover_tries, config.terminal_chance);
if (!second)
return {};
return {{first, *second}};
}
std::optional<crossover_t::crossover_point_t> crossover_t::get_crossover_point_traverse(const tree_t& c1,
const tree_t& c2) const
{
auto c1_point_o = get_point_traverse_retry(c1, {});
if (!c1_point_o)
return {};
auto c2_point_o = get_point_traverse_retry(c2, c1_point_o->type);
if (!c2_point_o)
return {};
return {{*c1_point_o, *c2_point_o}};
}
std::optional<tree_t::subtree_point_t> crossover_t::get_point_traverse_retry(const tree_t& t, const std::optional<type_id> type) const
{
if (type)
return t.select_subtree_traverse(*type, config.max_crossover_tries, config.terminal_chance, config.depth_multiplier);
return t.select_subtree_traverse(config.terminal_chance, config.depth_multiplier);
}
bool mutation_t::apply(gp_program& program, const tree_t&, tree_t& c)

View File

@ -293,13 +293,13 @@ namespace blt::gp
stack.copy_from(values, for_bytes, after_bytes);
}
void tree_t::swap_subtrees(const subtree_point_t our_subtree, tree_t& other_tree, const subtree_point_t other_subtree)
void tree_t::swap_subtrees(const child_t our_subtree, tree_t& other_tree, const child_t other_subtree)
{
const auto c1_subtree_begin_itr = operations.begin() + our_subtree.pos;
const auto c1_subtree_end_itr = operations.begin() + find_endpoint(our_subtree.pos);
const auto c1_subtree_begin_itr = operations.begin() + our_subtree.start;
const auto c1_subtree_end_itr = operations.begin() + our_subtree.end;
const auto c2_subtree_begin_itr = other_tree.operations.begin() + other_subtree.pos;
const auto c2_subtree_end_itr = other_tree.operations.begin() + other_tree.find_endpoint(other_subtree.pos);
const auto c2_subtree_begin_itr = other_tree.operations.begin() + other_subtree.start;
const auto c2_subtree_end_itr = other_tree.operations.begin() + other_subtree.end;
thread_local tracked_vector<op_container_t> c1_subtree_operators;
thread_local tracked_vector<op_container_t> c2_subtree_operators;
@ -349,8 +349,8 @@ namespace blt::gp
const auto copy_ptr_c1 = get_thread_pointer_for_size<struct c1_t>(c1_total);
const auto copy_ptr_c2 = get_thread_pointer_for_size<struct c2_t>(c2_total);
values.reserve(values.bytes_in_head() - c1_subtree_bytes + c2_subtree_bytes);
other_tree.values.reserve(other_tree.values.bytes_in_head() - c2_subtree_bytes + c1_subtree_bytes);
values.reserve(values.stored() - c1_subtree_bytes + c2_subtree_bytes);
other_tree.values.reserve(other_tree.values.stored() - c2_subtree_bytes + c1_subtree_bytes);
values.copy_to(copy_ptr_c1, c1_total);
values.pop_bytes(c1_total);
@ -376,6 +376,12 @@ namespace blt::gp
other_tree.operations.insert(insert_point_c2, c1_subtree_operators.begin(), c1_subtree_operators.end());
}
void tree_t::swap_subtrees(const subtree_point_t our_subtree, tree_t& other_tree, const subtree_point_t other_subtree)
{
swap_subtrees(child_t{our_subtree.pos, find_endpoint(our_subtree.pos)}, other_tree,
child_t{other_subtree.pos, other_tree.find_endpoint(other_subtree.pos)});
}
void tree_t::replace_subtree(const subtree_point_t point, const ptrdiff_t extent, tree_t& other_tree)
{
const auto point_begin_itr = operations.begin() + point.pos;
@ -535,7 +541,7 @@ namespace blt::gp
bool tree_t::check(void* context) const
{
size_t bytes_expected = 0;
const auto bytes_size = values.size().total_used_bytes;
const auto bytes_size = values.stored();
for (const auto& op : operations)
{
@ -545,7 +551,7 @@ namespace blt::gp
if (bytes_expected != bytes_size)
{
BLT_ERROR("Stack state: {}", values.size());
BLT_ERROR("Stack state: Stored: {}; Capacity: {}; Remainder: {}", values.stored(), values.capacity(), values.remainder());
BLT_ERROR("Child tree bytes {} vs expected {}, difference: {}", bytes_size, bytes_expected,
static_cast<ptrdiff_t>(bytes_expected) - static_cast<ptrdiff_t>(bytes_size));
BLT_ERROR("Amount of bytes in stack doesn't match the number of bytes expected for the operations");
@ -580,7 +586,7 @@ namespace blt::gp
total_produced += m_program->get_typesystem().get_type(info.return_type).size();
}
const auto v1 = results.values.bytes_in_head();
const auto v1 = static_cast<ptrdiff_t>(results.values.stored());
const auto v2 = static_cast<ptrdiff_t>(operations.front().type_size());
// ephemeral don't need to be dropped as there are no copies which matter when checking the tree
@ -668,6 +674,91 @@ namespace blt::gp
return {point, m_program->get_operator_info(operations[point].id()).return_type};
}
size_t tree_t::required_size() const
{
// 2 size_t used to store expected_length of operations + size of the values stack
return 2 * sizeof(size_t) + operations.size() * sizeof(size_t) + values.stored();
}
void tree_t::to_byte_array(std::byte* out) const
{
const auto op_size = operations.size();
std::memcpy(out, &op_size, sizeof(size_t));
out += sizeof(size_t);
for (const auto& op : operations)
{
constexpr auto size_of_op = sizeof(operator_id);
auto id = op.id();
std::memcpy(out, &id, size_of_op);
out += size_of_op;
}
const auto val_size = values.stored();
std::memcpy(out, &val_size, sizeof(size_t));
out += sizeof(size_t);
std::memcpy(out, values.data(), val_size);
}
void tree_t::to_file(fs::writer_t& file) const
{
const auto op_size = operations.size();
BLT_ASSERT(file.write(&op_size, sizeof(size_t)) == sizeof(size_t));
for (const auto& op : operations)
{
auto id = op.id();
file.write(&id, sizeof(operator_id));
}
const auto val_size = values.stored();
BLT_ASSERT(file.write(&val_size, sizeof(size_t)) == sizeof(size_t));
BLT_ASSERT(file.write(values.data(), val_size) == static_cast<i64>(val_size));
}
void tree_t::from_byte_array(const std::byte* in)
{
size_t ops_to_read;
std::memcpy(&ops_to_read, in, sizeof(size_t));
in += sizeof(size_t);
operations.reserve(ops_to_read);
for (size_t i = 0; i < ops_to_read; i++)
{
operator_id id;
std::memcpy(&id, in, sizeof(operator_id));
in += sizeof(operator_id);
operations.emplace_back(
m_program->get_typesystem().get_type(m_program->get_operator_info(id).return_type).size(),
id,
m_program->is_operator_ephemeral(id),
m_program->get_operator_flags(id)
);
}
size_t val_size;
std::memcpy(&val_size, in, sizeof(size_t));
in += sizeof(size_t);
// TODO replace instances of u8 that are used to alias types with the proper std::byte
values.copy_from(reinterpret_cast<const u8*>(in), val_size);
}
void tree_t::from_file(fs::reader_t& file)
{
size_t ops_to_read;
BLT_ASSERT(file.read(&ops_to_read, sizeof(size_t)) == sizeof(size_t));
operations.reserve(ops_to_read);
for (size_t i = 0; i < ops_to_read; i++)
{
operator_id id;
BLT_ASSERT(file.read(&id, sizeof(operator_id)) == sizeof(operator_id));
operations.emplace_back(
m_program->get_typesystem().get_type(m_program->get_operator_info(id).return_type).size(),
id,
m_program->is_operator_ephemeral(id),
m_program->get_operator_flags(id)
);
}
size_t bytes_in_head;
BLT_ASSERT(file.read(&bytes_in_head, sizeof(size_t)) == sizeof(size_t));
values.resize(bytes_in_head);
BLT_ASSERT(file.read(values.data(), bytes_in_head) == static_cast<i64>(bytes_in_head));
}
void tree_t::modify_operator(const size_t point, operator_id new_id, std::optional<type_id> return_type)
{
if (!return_type)
@ -702,4 +793,23 @@ namespace blt::gp
handle_operator_inserted(operations[point]);
}
}
bool operator==(const tree_t& a, const tree_t& b)
{
if (a.operations.size() != b.operations.size())
return false;
if (a.values.stored() != b.values.stored())
return false;
return std::equal(a.operations.begin(), a.operations.end(), b.operations.begin());
}
bool operator==(const op_container_t& a, const op_container_t& b)
{
return a.id() == b.id();
}
bool operator==(const individual_t& a, const individual_t& b)
{
return a.tree == b.tree;
}
}

View File

@ -0,0 +1,171 @@
/*
* <Short Description>
* Copyright (C) 2025 Brett Terpstra
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <filesystem>
#include "../examples/symbolic_regression.h"
#include <blt/gp/program.h>
#include <blt/logging/logging.h>
#include <ostream>
#include <istream>
#include <fstream>
#include <blt/fs/stream_wrappers.h>
using namespace blt::gp;
struct context
{
float x, y;
};
prog_config_t config = prog_config_t()
.set_initial_min_tree_size(2)
.set_initial_max_tree_size(6)
.set_elite_count(2)
.set_crossover_chance(0.8)
.set_mutation_chance(0.1)
.set_reproduction_chance(0.1)
.set_max_generations(50)
.set_pop_size(500)
.set_thread_count(1);
example::symbolic_regression_t regression{691ul, config};
operation_t addf{[](const float a, const float b) { return a + b; }, "addf"};
operation_t subf([](const float a, const float b) { return a - b; }, "subf");
operation_t mulf([](const float a, const float b) { return a * b; }, "mulf");
operation_t pro_divf([](const float a, const float b) { return b == 0.0f ? 0.0f : a / b; }, "divf");
operation_t op_sinf([](const float a) { return std::sin(a); }, "sinf");
operation_t op_cosf([](const float a) { return std::cos(a); }, "cosf");
operation_t op_expf([](const float a) { return std::exp(a); }, "expf");
operation_t op_logf([](const float a) { return a <= 0.0f ? 0.0f : std::log(a); }, "logf");
auto litf = operation_t([]()
{
return regression.get_program().get_random().get_float(-1.0f, 1.0f);
}, "litf").set_ephemeral();
operation_t op_xf([](const context& context)
{
return context.x;
}, "xf");
bool fitness_function(const tree_t& current_tree, fitness_t& fitness, size_t)
{
constexpr static double value_cutoff = 1.e15;
for (auto& fitness_case : regression.get_training_cases())
{
BLT_GP_UPDATE_CONTEXT(fitness_case);
auto val = current_tree.get_evaluation_ref<float>(fitness_case);
const auto diff = std::abs(fitness_case.y - val.get());
if (diff < value_cutoff)
{
fitness.raw_fitness += diff;
if (diff <= 0.01)
fitness.hits++;
}
else
fitness.raw_fitness += value_cutoff;
}
fitness.standardized_fitness = fitness.raw_fitness;
fitness.adjusted_fitness = (1.0 / (1.0 + fitness.standardized_fitness));
return static_cast<size_t>(fitness.hits) == regression.get_training_cases().size();
}
int main()
{
operator_builder<context> builder{};
const auto& operators = builder.build(addf, subf, mulf, pro_divf, op_sinf, op_cosf, op_expf, op_logf, litf, op_xf);
regression.get_program().set_operations(operators);
auto& program = regression.get_program();
static auto sel = select_tournament_t{};
gp_program test_program{691};
test_program.set_operations(operators);
test_program.setup_generational_evaluation(fitness_function, sel, sel, sel, false);
// simulate a program which is similar but incompatible with the other programs.
operator_builder<context> builder2{};
gp_program bad_program{691};
bad_program.set_operations(builder2.build(addf, subf, mulf, op_sinf, op_cosf, litf, op_xf));
bad_program.setup_generational_evaluation(fitness_function, sel, sel, sel, false);
program.generate_initial_population(program.get_typesystem().get_type<float>().id());
program.setup_generational_evaluation(fitness_function, sel, sel, sel);
while (!program.should_terminate())
{
BLT_TRACE("---------------\\{Begin Generation {}}---------------", program.get_current_generation());
BLT_TRACE("Creating next generation");
program.create_next_generation();
BLT_TRACE("Move to next generation");
program.next_generation();
BLT_TRACE("Evaluate Fitness");
program.evaluate_fitness();
{
std::ofstream stream{"serialization_test.data", std::ios::binary | std::ios::trunc};
blt::fs::fstream_writer_t writer{stream};
program.save_generation(writer);
}
{
std::ifstream stream{"serialization_test.data", std::ios::binary};
blt::fs::fstream_reader_t reader{stream};
test_program.load_generation(reader);
}
// do a quick validation check
for (const auto& [saved, loaded] : blt::zip(program.get_current_pop(), test_program.get_current_pop()))
{
if (saved.tree != loaded.tree)
{
BLT_ERROR("Serializer Failed to correctly serialize tree to disk, trees are not equal!");
std::exit(1);
}
}
}
{
std::ofstream stream{"serialization_test2.data", std::ios::binary | std::ios::trunc};
blt::fs::fstream_writer_t writer{stream};
program.save_state(writer);
}
{
std::ifstream stream{"serialization_test2.data", std::ios::binary};
blt::fs::fstream_reader_t reader{stream};
if (auto error = test_program.load_state(reader))
{
BLT_ERROR("Error: {}", error->call_member(&errors::serialization::error_to_string_t::to_string));
BLT_ABORT("Expected program to succeeded without returning an error state!");
}
for (const auto [saved, loaded] : blt::zip(program.get_stats_histories(), test_program.get_stats_histories()))
{
if (saved != loaded)
{
BLT_ERROR("Serializer Failed to correctly serialize histories to disk, histories are not equal!");
std::exit(1);
}
}
}
{
std::ifstream stream{"serialization_test2.data", std::ios::binary};
blt::fs::fstream_reader_t reader{stream};
if (!bad_program.load_state(reader))
{
BLT_ABORT("Expected program to throw an exception when parsing state data into an incompatible program!");
}
}
}