diff options
Diffstat (limited to 'src/development/c++')
-rw-r--r-- | src/development/c++/.clang-format | 104 | ||||
-rw-r--r-- | src/development/c++/meta.cc | 34 | ||||
-rw-r--r-- | src/development/c++/meta2.cc | 85 |
3 files changed, 223 insertions, 0 deletions
diff --git a/src/development/c++/.clang-format b/src/development/c++/.clang-format new file mode 100644 index 0000000..3cfb373 --- /dev/null +++ b/src/development/c++/.clang-format @@ -0,0 +1,104 @@ +# dotfiles -- clang-format +# author: johannst +# doc : https://clang.llvm.org/docs/ClangFormatStyleOptions.html + +Language: Cpp +Standard: Auto + +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveMacros: true +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Left +AlignOperands: true +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: true +BinPackParameters: true +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: AfterColon +BreakConstructorInitializersBeforeComma: false +BreakInheritanceList: BeforeColon +BreakBeforeInheritanceComma: false +BreakStringLiterals: true +ColumnLimit: 100 +CompactNamespaces: true +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 2 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +IncludeBlocks: Preserve +# Could use `IncludeCategories` to define rules for includes +IndentCaseLabels: true +IndentPPDirectives: AfterHash +IndentWidth: 4 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 2 +NamespaceIndentation: All +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: true +SpacesInParentheses: false +SpacesInSquareBrackets: false +TabWidth: 4 +UseTab: Never diff --git a/src/development/c++/meta.cc b/src/development/c++/meta.cc new file mode 100644 index 0000000..e674cfd --- /dev/null +++ b/src/development/c++/meta.cc @@ -0,0 +1,34 @@ +// Copyright (C) 2022 johannst + +#include <iostream> + +// Base case with one parameter. +template<int P> +void show_int() { + printf("%d\n", P); +} + +// General case with at least two parameters, to disambiguate from base case. +template<int P0, int P1, int... Params> +void show_int() { + printf("%d, ", P0); + show_int<P1, Params...>(); +} + +// Base case with one parameter. +template<typename T> +void show(const T& t) { + std::cout << t << '\n'; +} + +// General case with at least two parameters, to disambiguate from base case. +template<typename T0, typename T1, typename... Types> +void show(const T0& t0, const T1& t1, const Types&... types) { + std::cout << t0 << ", "; + show(t1, types...); +} + +int main() { + show_int<1, 2, 3, 4, 5>(); + show(1, 1.0, "foo", 'a'); +} diff --git a/src/development/c++/meta2.cc b/src/development/c++/meta2.cc new file mode 100644 index 0000000..4c1194f --- /dev/null +++ b/src/development/c++/meta2.cc @@ -0,0 +1,85 @@ +// Copyright (C) 2022 johannst + +#include <iostream> +#include <type_traits> + +// Helper meta fns. + +template<typename T> +using enable_if_bool = std::enable_if_t<T::value, bool>; + +template<typename T> +using disable_if_bool = std::enable_if_t<!T::value, bool>; + +template<typename T> +using has_dst = std::integral_constant<bool, !std::is_same<typename T::Return, void>::value>; + +// Template meta programming invoke machinery. + +namespace impl { + // Invoke an OPERATION which *USES* a context. + template<typename Ctx, template<typename> class Op, typename... P, + enable_if_bool<typename Op<Ctx>::HasCtx> = true> + typename Op<Ctx>::Return Invoke(const Ctx& C, P... params) { + return Op<Ctx>()(C, params...); + } + + // Invoke an OPERATION which uses *NO* context. + template<typename Ctx, template<typename> class Op, typename... P, + disable_if_bool<typename Op<Ctx>::HasCtx> = true> + typename Op<Ctx>::Return Invoke(const Ctx&, P... params) { + return Op<Ctx>()(params...); + } +} // namespace impl + +// Invoke an OPERATION which *HAS* a DESTINATION with arbitrary number of arguments. +template<typename Ctx, template<typename> class Op, typename... P, + enable_if_bool<has_dst<Op<Ctx>>> = true> +void Invoke(const Ctx& C, P... params) { + std::cout << "Invoke " << Op<Ctx>::Name << '\n'; + typename Op<Ctx>::Return R = impl::Invoke<Ctx, Op>(C, params...); + std::cout << "returned -> " << R << '\n'; +} + +// Invoke an OPERATION which has *NOT* a DESTINATION with arbitrary number of arguments. +template<typename Ctx, template<typename> class Op, typename... P, + disable_if_bool<has_dst<Op<Ctx>>> = true> +void Invoke(const Ctx& C, P... params) { + std::cout << "Invoke " << Op<Ctx>::Name << " without destination." << '\n'; + impl::Invoke<Ctx, Op>(C, params...); +} + +// Custom context. + +struct Ctx { + void out(const char* s, unsigned v) const { printf("%s%x\n", s, v); } +}; + +// Operations to invoke. + +template<typename Ctx> +struct OpA { + using HasCtx = std::false_type; + using Return = int; + static constexpr const char* const Name = "OpA"; + + constexpr Return operator()(int a, int b) const { return a + b; } +}; + +template<typename Ctx> +struct OpB { + using HasCtx = std::true_type; + using Return = void; + static constexpr const char* const Name = "OpB"; + + Return operator()(const Ctx& C, unsigned a) const { C.out("a = ", a); } +}; + +int main() { + Ctx C; + + Invoke<Ctx, OpA>(C, 1, 2); + Invoke<Ctx, OpB>(C, 0xf00du); + + return 0; +} |