From 6d7baf83e7694387f98aa0f0e8ae18bf77d5c249 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leroy Date: Sun, 5 Dec 2021 08:50:24 -0500 Subject: [PATCH] clang-format (just the lib for now) --- clang-llvm | 137 +++++++ include/yorel/yomm2.hpp | 607 +++++++++++++++----------------- include/yorel/yomm2/runtime.hpp | 22 +- src/yomm2.cpp | 351 +++++++++--------- 4 files changed, 599 insertions(+), 518 deletions(-) create mode 100644 clang-llvm diff --git a/clang-llvm b/clang-llvm new file mode 100644 index 00000000..33bf2a3b --- /dev/null +++ b/clang-llvm @@ -0,0 +1,137 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveMacros: false +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Right +AlignOperands: true +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + - Regex: '.*' + Priority: 1 + SortPriority: 0 +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentCaseLabels: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentWidth: 2 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +Standard: Latest +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseCRLF: false +UseTab: Never +... + diff --git a/include/yorel/yomm2.hpp b/include/yorel/yomm2.hpp index a9bb3d3d..78bdb85d 100644 --- a/include/yorel/yomm2.hpp +++ b/include/yorel/yomm2.hpp @@ -17,24 +17,24 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include -#include +#include #include #include #include #include -#include +#include #include #include #include #include - #ifndef YOMM2_ENABLE_TRACE +#ifndef YOMM2_ENABLE_TRACE #ifdef NDEBUG #define YOMM2_ENABLE_TRACE 0 #else @@ -56,203 +56,227 @@ #define yOMM2_GENSYM BOOST_PP_CAT(YoMm2_nS_, __COUNTER__) -#define yOMM2_PLIST(N, I, A) \ - BOOST_PP_COMMA_IF(I) \ - ::yorel::yomm2::detail::virtual_arg_t \ +#define yOMM2_PLIST(N, I, A) \ + BOOST_PP_COMMA_IF(I) \ + ::yorel::yomm2::detail::virtual_arg_t \ BOOST_PP_CAT(a, I) -#define yOMM2_PPLIST(N, I, A) \ - BOOST_PP_COMMA_IF(I) \ - ::yorel::yomm2::detail::virtual_arg_t* \ +#define yOMM2_PPLIST(N, I, A) \ + BOOST_PP_COMMA_IF(I) \ + ::yorel::yomm2::detail::virtual_arg_t* \ BOOST_PP_CAT(a, I) -#define yOMM2_ALIST(N, I, A) \ - BOOST_PP_COMMA_IF(I) \ - std::forward<::yorel::yomm2::detail::virtual_arg_t>(BOOST_PP_CAT(a, I)) +#define yOMM2_ALIST(N, I, A) \ + BOOST_PP_COMMA_IF(I) \ + std::forward< \ + ::yorel::yomm2::detail::virtual_arg_t>( \ + BOOST_PP_CAT(a, I)) -#define yOMM2_RLIST(N, I, A) \ - BOOST_PP_COMMA_IF(I) \ +#define yOMM2_RLIST(N, I, A) \ + BOOST_PP_COMMA_IF(I) \ BOOST_PP_CAT(a, I) -#define yOMM2_DECLARE_KEY(ID) \ - BOOST_PP_CAT(_yomm2_method_, ID) +#define yOMM2_DECLARE_KEY(ID) BOOST_PP_CAT(_yomm2_method_, ID) #if !BOOST_PP_VARIADICS_MSVC -#define YOMM2_DECLARE(...) \ - BOOST_PP_OVERLOAD(YOMM2_DECLARE_, __VA_ARGS__) \ +#define YOMM2_DECLARE(...) \ + BOOST_PP_OVERLOAD(YOMM2_DECLARE_, __VA_ARGS__) \ (__VA_ARGS__) -#define YOMM2_STATIC_DECLARE(...) \ - BOOST_PP_OVERLOAD(YOMM2_STATIC_DECLARE_, __VA_ARGS__) \ +#define YOMM2_STATIC_DECLARE(...) \ + BOOST_PP_OVERLOAD(YOMM2_STATIC_DECLARE_, __VA_ARGS__) \ (__VA_ARGS__) #else -#define YOMM2_DECLARE(...) \ - BOOST_PP_CAT(BOOST_PP_OVERLOAD(YOMM2_DECLARE_, __VA_ARGS__)(__VA_ARGS__), BOOST_PP_EMPTY()) -#define YOMM2_STATIC_DECLARE(...) \ - BOOST_PP_CAT(BOOST_PP_OVERLOAD(YOMM2_STATIC_DECLARE_, __VA_ARGS__)(__VA_ARGS__), BOOST_PP_EMPTY()) +#define YOMM2_DECLARE(...) \ + BOOST_PP_CAT( \ + BOOST_PP_OVERLOAD(YOMM2_DECLARE_, __VA_ARGS__)(__VA_ARGS__), \ + BOOST_PP_EMPTY()) +#define YOMM2_STATIC_DECLARE(...) \ + BOOST_PP_CAT( \ + BOOST_PP_OVERLOAD(YOMM2_STATIC_DECLARE_, __VA_ARGS__)(__VA_ARGS__), \ + BOOST_PP_EMPTY()) #endif #define yOMM2_WHEN_STATIC(CODE1, CODE2) CODE1 #define yOMM2_WHEN_NOT_STATIC(CODE1, CODE2) CODE2 -#define YOMM2_DECLARE_3(R, ID, ARGS) yOMM2_DECLARE(yOMM2_GENSYM, R, ID, ARGS, yOMM2_WHEN_NOT_STATIC, ::yorel::yomm2::default_policy) +#define YOMM2_DECLARE_3(R, ID, ARGS) \ + yOMM2_DECLARE( \ + yOMM2_GENSYM, R, ID, ARGS, yOMM2_WHEN_NOT_STATIC, \ + ::yorel::yomm2::default_policy) -#define YOMM2_DECLARE_4(R, ID, ARGS, POLICY) \ +#define YOMM2_DECLARE_4(R, ID, ARGS, POLICY) \ yOMM2_DECLARE(yOMM2_GENSYM, R, ID, ARGS, yOMM2_WHEN_NOT_STATIC, POLICY) -#define YOMM2_STATIC_DECLARE_3(R, ID, ARGS) yOMM2_DECLARE(yOMM2_GENSYM, R, ID, ARGS, yOMM2_WHEN_STATIC, ::yorel::yomm2::default_policy) +#define YOMM2_STATIC_DECLARE_3(R, ID, ARGS) \ + yOMM2_DECLARE( \ + yOMM2_GENSYM, R, ID, ARGS, yOMM2_WHEN_STATIC, \ + ::yorel::yomm2::default_policy) -#define YOMM2_STATIC_DECLARE_4(R, ID, ARGS, POLICY) \ +#define YOMM2_STATIC_DECLARE_4(R, ID, ARGS, POLICY) \ yOMM2_DECLARE(yOMM2_GENSYM, R, ID, ARGS, yOMM2_WHEN_STATIC, POLICY) #define yOMM2_OPEN_BRACE { #define yOMM2_CLOSE_BRACE } -#define yOMM2_SELECTOR(ID) ID ## _yOMM2_selector_ - -#define yOMM2_DECLARE(NS, R, ID, ARGS, IF_STATIC, POLICY) \ - struct yOMM2_DECLARE_KEY(ID); \ - IF_STATIC(, namespace yOMM2_OPEN_BRACE) \ - struct NS \ - { \ - using _yOMM2_method = ::yorel::yomm2::detail::method< \ - yOMM2_DECLARE_KEY(ID), R ARGS, POLICY>; \ - }; \ - IF_STATIC(, yOMM2_CLOSE_BRACE) \ - IF_STATIC(static, ) \ - NS::_yOMM2_method yOMM2_SELECTOR(ID)( \ - BOOST_PP_REPEAT(BOOST_PP_TUPLE_SIZE(ARGS), yOMM2_PLIST, ARGS)); \ - IF_STATIC(static, ) \ - inline const char *yOMM2_SELECTOR(ID)(NS::_yOMM2_method) \ - { \ - return #R " " #ID #ARGS; \ - } \ - IF_STATIC(static, ) \ - inline R ID(BOOST_PP_REPEAT(BOOST_PP_TUPLE_SIZE(ARGS), yOMM2_PLIST, ARGS)) \ - { \ - auto pf = NS::_yOMM2_method::resolve( \ - BOOST_PP_REPEAT(BOOST_PP_TUPLE_SIZE(ARGS), yOMM2_RLIST, ARGS)); \ - return pf(BOOST_PP_REPEAT(BOOST_PP_TUPLE_SIZE(ARGS), yOMM2_ALIST, ARGS)); \ +#define yOMM2_SELECTOR(ID) ID##_yOMM2_selector_ + +#define yOMM2_DECLARE(NS, R, ID, ARGS, IF_STATIC, POLICY) \ + struct yOMM2_DECLARE_KEY(ID); \ + IF_STATIC(, namespace yOMM2_OPEN_BRACE) \ + struct NS { \ + using _yOMM2_method = ::yorel::yomm2::detail::method< \ + yOMM2_DECLARE_KEY(ID), R ARGS, POLICY>; \ + }; \ + IF_STATIC(, yOMM2_CLOSE_BRACE) \ + IF_STATIC(static, ) \ + NS::_yOMM2_method yOMM2_SELECTOR(ID)( \ + BOOST_PP_REPEAT(BOOST_PP_TUPLE_SIZE(ARGS), yOMM2_PLIST, ARGS)); \ + IF_STATIC(static, ) \ + inline const char* yOMM2_SELECTOR(ID)(NS::_yOMM2_method) { \ + return #R " " #ID #ARGS; \ + } \ + IF_STATIC(static, ) \ + inline R ID( \ + BOOST_PP_REPEAT(BOOST_PP_TUPLE_SIZE(ARGS), yOMM2_PLIST, ARGS)) { \ + auto pf = NS::_yOMM2_method::resolve( \ + BOOST_PP_REPEAT(BOOST_PP_TUPLE_SIZE(ARGS), yOMM2_RLIST, ARGS)); \ + return pf( \ + BOOST_PP_REPEAT(BOOST_PP_TUPLE_SIZE(ARGS), yOMM2_ALIST, ARGS)); \ } #if !BOOST_PP_VARIADICS_MSVC -#define YOMM2_DEFINE(...) \ +#define YOMM2_DEFINE(...) \ BOOST_PP_OVERLOAD(YOMM2_DEFINE_, __VA_ARGS__)(__VA_ARGS__) #else -#define YOMM2_DEFINE(...) \ - BOOST_PP_CAT( \ - BOOST_PP_OVERLOAD(YOMM2_DEFINE_, __VA_ARGS__)(__VA_ARGS__), BOOST_PP_EMPTY()) +#define YOMM2_DEFINE(...) \ + BOOST_PP_CAT( \ + BOOST_PP_OVERLOAD(YOMM2_DEFINE_, __VA_ARGS__)(__VA_ARGS__), \ + BOOST_PP_EMPTY()) #endif -#define YOMM2_DEFINE_3(RETURN_T, ID, ARGS) \ +#define YOMM2_DEFINE_3(RETURN_T, ID, ARGS) \ yOMM2_DEFINE(yOMM2_GENSYM, RETURN_T, ID, ARGS) -#define yOMM2_SELECT_METHOD(RETURN_T, ID, ARGS) \ - template \ - struct _yOMM2_select; \ - template \ - struct _yOMM2_select \ - { \ - using type = decltype(yOMM2_SELECTOR(ID)(std::declval()...)); \ - }; \ - using _yOMM2_method = _yOMM2_select::type; \ - using _yOMM2_return_t = _yOMM2_method::return_type; \ - inline _yOMM2_method::init_method _yOMM2_init_method(yOMM2_SELECTOR(ID)(_yOMM2_method())); - -#define yOMM2_DEFINE(NS, RETURN_T, ID, ARGS) \ - namespace { \ - namespace NS { \ - yOMM2_SELECT_METHOD(RETURN_T, ID, ARGS); \ - _yOMM2_method::function_pointer_type next; \ - struct _yOMM2_spec { static RETURN_T yOMM2_body ARGS; }; \ - ::yorel::yomm2::detail:: \ - register_spec<_yOMM2_return_t, _yOMM2_method, _yOMM2_spec, void ARGS> \ - _yOMM2_init( \ - (void**)&next, YOMM2_TRACE_ELSE(#ARGS, typeid(_yOMM2_spec).name())); \ - } } \ +#define yOMM2_SELECT_METHOD(RETURN_T, ID, ARGS) \ + template \ + struct _yOMM2_select; \ + template \ + struct _yOMM2_select { \ + using type = decltype(yOMM2_SELECTOR(ID)(std::declval()...)); \ + }; \ + using _yOMM2_method = _yOMM2_select::type; \ + using _yOMM2_return_t = _yOMM2_method::return_type; \ + inline _yOMM2_method::init_method _yOMM2_init_method( \ + yOMM2_SELECTOR(ID)(_yOMM2_method())); + +#define yOMM2_DEFINE(NS, RETURN_T, ID, ARGS) \ + namespace { \ + namespace NS { \ + yOMM2_SELECT_METHOD(RETURN_T, ID, ARGS); \ + _yOMM2_method::function_pointer_type next; \ + struct _yOMM2_spec { \ + static RETURN_T yOMM2_body ARGS; \ + }; \ + ::yorel::yomm2::detail::register_spec< \ + _yOMM2_return_t, _yOMM2_method, _yOMM2_spec, void ARGS> \ + _yOMM2_init( \ + (void**) &next, \ + YOMM2_TRACE_ELSE(#ARGS, typeid(_yOMM2_spec).name())); \ + } \ + } \ RETURN_T NS::_yOMM2_spec::yOMM2_body ARGS - #if !BOOST_PP_VARIADICS_MSVC -#define YOMM2_DECLARE_METHOD_CONTAINER(...) \ +#define YOMM2_DECLARE_METHOD_CONTAINER(...) \ BOOST_PP_OVERLOAD(YOMM2_DECLARE_METHOD_CONTAINER_, __VA_ARGS__)(__VA_ARGS__) #else -#define YOMM2_DECLARE_METHOD_CONTAINER(...) \ - BOOST_PP_CAT(BOOST_PP_OVERLOAD(YOMM2_DECLARE_METHOD_CONTAINER_, __VA_ARGS__) \ - (__VA_ARGS__), BOOST_PP_EMPTY()) +#define YOMM2_DECLARE_METHOD_CONTAINER(...) \ + BOOST_PP_CAT( \ + BOOST_PP_OVERLOAD(YOMM2_DECLARE_METHOD_CONTAINER_, __VA_ARGS__)( \ + __VA_ARGS__), \ + BOOST_PP_EMPTY()) #endif -#define YOMM2_DECLARE_METHOD_CONTAINER_1(CONTAINER) \ - template struct CONTAINER +#define YOMM2_DECLARE_METHOD_CONTAINER_1(CONTAINER) \ + template \ + struct CONTAINER -#define YOMM2_DECLARE_METHOD_CONTAINER_4(CONTAINER, RETURN_T, ID, ARGS) \ - template struct CONTAINER; \ - YOMM2_DECLARE_METHOD_CONTAINER_4_NS(yOMM2_GENSYM, CONTAINER, RETURN_T, ID, ARGS) \ +#define YOMM2_DECLARE_METHOD_CONTAINER_4(CONTAINER, RETURN_T, ID, ARGS) \ + template \ + struct CONTAINER; \ + YOMM2_DECLARE_METHOD_CONTAINER_4_NS( \ + yOMM2_GENSYM, CONTAINER, RETURN_T, ID, ARGS) #define YOMM2_DECLARE_METHOD_CONTAINER_4_NS(NS, CONTAINER, RETURN_T, ID, ARGS) \ - template struct CONTAINER; \ - namespace { namespace NS { \ - yOMM2_SELECT_METHOD(RETURN_T, ID, ARGS); \ - } } \ - template<> struct CONTAINER { \ - static NS::_yOMM2_method::function_pointer_type next; \ - static RETURN_T yOMM2_body ARGS; \ + template \ + struct CONTAINER; \ + namespace { \ + namespace NS { \ + yOMM2_SELECT_METHOD(RETURN_T, ID, ARGS); \ + } \ + } \ + template<> \ + struct CONTAINER { \ + static NS::_yOMM2_method::function_pointer_type next; \ + static RETURN_T yOMM2_body ARGS; \ } -#define YOMM2_DEFINE_4(CONTAINER, RETURN_T, ID, ARGS) \ +#define YOMM2_DEFINE_4(CONTAINER, RETURN_T, ID, ARGS) \ yOMM2_DEFINE_METHOD_IN(yOMM2_GENSYM, , CONTAINER, RETURN_T, ID, ARGS) -#define YOMM2_DEFINE_INLINE(CONTAINER, RETURN_T, ID, ARGS) \ +#define YOMM2_DEFINE_INLINE(CONTAINER, RETURN_T, ID, ARGS) \ yOMM2_DEFINE_METHOD_IN(yOMM2_GENSYM, inline, CONTAINER, RETURN_T, ID, ARGS) -#define yOMM2_DEFINE_METHOD_IN(NS, INLINE, CONTAINER, RETURN_T, ID, ARGS) \ - YOMM2_DECLARE_METHOD_CONTAINER_4_NS(NS, CONTAINER, RETURN_T, ID, ARGS); \ - INLINE NS::_yOMM2_method::function_pointer_type CONTAINER::next; \ - namespace \ - { \ - namespace NS \ - { \ - INLINE ::yorel::yomm2::detail:: \ - register_spec<_yOMM2_return_t, _yOMM2_method, CONTAINER, void ARGS> \ - _yOMM2_init( \ - (void **)&CONTAINER::next, \ - YOMM2_TRACE_ELSE(#ARGS, typeid(CONTAINER).name())); \ - } \ - } \ +#define yOMM2_DEFINE_METHOD_IN(NS, INLINE, CONTAINER, RETURN_T, ID, ARGS) \ + YOMM2_DECLARE_METHOD_CONTAINER_4_NS(NS, CONTAINER, RETURN_T, ID, ARGS); \ + INLINE NS::_yOMM2_method::function_pointer_type \ + CONTAINER::next; \ + namespace { \ + namespace NS { \ + INLINE ::yorel::yomm2::detail::register_spec< \ + _yOMM2_return_t, _yOMM2_method, CONTAINER, void ARGS> \ + _yOMM2_init( \ + (void**) &CONTAINER::next, \ + YOMM2_TRACE_ELSE(#ARGS, typeid(CONTAINER).name())); \ + } \ + } \ INLINE RETURN_T CONTAINER::yOMM2_body ARGS #if !BOOST_PP_VARIADICS_MSVC -#define YOMM2_FRIEND(...) \ +#define YOMM2_FRIEND(...) \ BOOST_PP_OVERLOAD(YOMM2_FRIEND_, __VA_ARGS__)(__VA_ARGS__) #else -#define YOMM2_FRIEND(...) \ - BOOST_PP_CAT(BOOST_PP_OVERLOAD(YOMM2_FRIEND_, __VA_ARGS__) \ - (__VA_ARGS__), BOOST_PP_EMPTY()) +#define YOMM2_FRIEND(...) \ + BOOST_PP_CAT( \ + BOOST_PP_OVERLOAD(YOMM2_FRIEND_, __VA_ARGS__)(__VA_ARGS__), \ + BOOST_PP_EMPTY()) #endif -#define YOMM2_FRIEND_1(CONTAINER) \ - template friend struct CONTAINER +#define YOMM2_FRIEND_1(CONTAINER) \ + template \ + friend struct CONTAINER -#define YOMM2_FRIEND_3(CONTAINER, RETURN_T, ARGS) \ +#define YOMM2_FRIEND_3(CONTAINER, RETURN_T, ARGS) \ friend struct CONTAINER -#define YOMM2_DEFINITION(CONTAINER, RETURN_T, ARGS) \ +#define YOMM2_DEFINITION(CONTAINER, RETURN_T, ARGS) \ CONTAINER::yOMM2_body -#define YOMM2_CLASS(...) \ +#define YOMM2_CLASS(...) \ YOMM2_CLASS_(::yorel::yomm2::default_registry, __VA_ARGS__) -#define YOMM2_CLASS_(...) \ +#define YOMM2_CLASS_(...) \ yOMM2_CLASS2(yOMM2_GENSYM, BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__)) -#define yOMM2_CLASS2(NS, TUPLE) \ - namespace { \ - namespace NS { \ - ::yorel::yomm2::detail:: \ - init_class_info \ - init \ - YOMM2_TRACE( { \ - BOOST_PP_STRINGIZE( \ - BOOST_PP_TUPLE_ELEM(BOOST_PP_TUPLE_SIZE(TUPLE), 1, TUPLE)) }); } } +#define yOMM2_CLASS2(NS, TUPLE) \ + namespace { \ + namespace NS { \ + ::yorel::yomm2::detail::init_class_info< \ + BOOST_PP_TUPLE_REM(BOOST_PP_TUPLE_SIZE(TUPLE)) TUPLE> \ + init YOMM2_TRACE({BOOST_PP_STRINGIZE( \ + BOOST_PP_TUPLE_ELEM(BOOST_PP_TUPLE_SIZE(TUPLE), 1, TUPLE))}); \ + } \ + } namespace yorel { namespace yomm2 { @@ -272,7 +296,7 @@ using method_call_error_handler = void (*)(const method_call_error& error); method_call_error_handler set_method_call_error_handler(method_call_error_handler handler); -struct default_registry; +struct default_registry; struct policy { struct hash_factors_in_globals {}; @@ -286,15 +310,15 @@ struct default_policy : policy { // IWYU pragma: no_forward_declare default_registry // IWYU pragma: no_forward_declare default_policy - + namespace detail { template struct next_ptr_t; template -struct next_ptr_t { - using type = R(*)(T...); +struct next_ptr_t { + using type = R (*)(T...); }; template @@ -316,10 +340,12 @@ union word { struct registry { std::vector classes; std::vector methods; - template static registry& get(); + template + static registry& get(); }; -template registry& registry::get() { +template +registry& registry::get() { static registry r; return r; } @@ -328,14 +354,13 @@ struct hash_function { std::uintptr_t mult; std::size_t shift; - std::size_t operator ()(const void* p) const { + std::size_t operator()(const void* p) const { return static_cast( (mult * reinterpret_cast(const_cast(p))) >> shift); } }; - inline std::size_t hash(std::uintptr_t mult, std::size_t shift, const void* p) { return static_cast( (mult * reinterpret_cast(const_cast(p))) @@ -364,13 +389,13 @@ inline const word* get_mptr( const word* hash_table, std::uintptr_t hash_mult, std::size_t hash_shift, const std::type_info* ti) { auto index = detail::hash(hash_mult, hash_shift, ti); - auto mptr = hash_table[index].pw; + auto mptr = hash_table[index].pw; #ifndef NDEBUG - if (!mptr || hash_table[-1].pw[index].ti != ti) { - unregistered_class_error(ti); - } + if (!mptr || hash_table[-1].pw[index].ti != ti) { + unregistered_class_error(ti); + } #endif - return mptr; + return mptr; } struct dynamic_cast_ {}; @@ -378,7 +403,8 @@ struct static_cast_ {}; template struct virtual_traits { - using polymorphic_type = typename std::remove_cv_t>; + using polymorphic_type = + typename std::remove_cv_t>; using argument_type = T; using resolve_type = const T&; template @@ -392,7 +418,7 @@ struct virtual_traits { }; template -struct virtual_traits< virtual_ > { +struct virtual_traits> { using polymorphic_type = std::remove_cv_t; using argument_type = T&; using resolve_type = T&; @@ -400,9 +426,7 @@ struct virtual_traits< virtual_ > { static_assert(std::is_class::value); static_assert(std::is_polymorphic::value); - static auto key(resolve_type arg) { - return &typeid(arg); - } + static auto key(resolve_type arg) { return &typeid(arg); } template static auto& cast(T& obj, static_cast_) { @@ -416,7 +440,7 @@ struct virtual_traits< virtual_ > { }; template -struct virtual_traits< virtual_ > { +struct virtual_traits> { using polymorphic_type = T; using argument_type = T&&; using resolve_type = T&; @@ -424,9 +448,7 @@ struct virtual_traits< virtual_ > { static_assert(std::is_class::value); static_assert(std::is_polymorphic::value); - static auto key(resolve_type arg) { - return &typeid(arg); - } + static auto key(resolve_type arg) { return &typeid(arg); } template static auto&& cast(T&& obj, static_cast_) { @@ -440,7 +462,7 @@ struct virtual_traits< virtual_ > { }; template -struct virtual_traits< virtual_ > { +struct virtual_traits> { using polymorphic_type = std::remove_cv_t; using argument_type = T*; using resolve_type = T*; @@ -448,9 +470,7 @@ struct virtual_traits< virtual_ > { static_assert(std::is_class::value); static_assert(std::is_polymorphic::value); - static auto key(resolve_type arg) { - return &typeid(*arg); - } + static auto key(resolve_type arg) { return &typeid(*arg); } template static auto cast(T* obj, static_cast_) { @@ -471,21 +491,21 @@ struct shared_ptr_traits { }; template -struct shared_ptr_traits< std::shared_ptr > { +struct shared_ptr_traits> { static const bool is_shared_ptr = true; static const bool is_const_ref = false; using polymorphic_type = T; }; template -struct shared_ptr_traits< const std::shared_ptr& > { +struct shared_ptr_traits&> { static const bool is_shared_ptr = true; static const bool is_const_ref = true; using polymorphic_type = T; }; template -struct virtual_traits< virtual_< std::shared_ptr > > { +struct virtual_traits>> { using polymorphic_type = std::remove_cv_t; using argument_type = std::shared_ptr; using resolve_type = const std::shared_ptr&; @@ -493,35 +513,37 @@ struct virtual_traits< virtual_< std::shared_ptr > > { static_assert(std::is_class::value); static_assert(std::is_polymorphic::value); - static auto key(resolve_type arg) { - return &typeid(*arg); - } + static auto key(resolve_type arg) { return &typeid(*arg); } template static void check_cast() { static_assert(shared_ptr_traits::is_shared_ptr); static_assert( - !shared_ptr_traits::is_const_ref, - "cannot cast from 'const shared_ptr&' to 'shared_ptr'"); + !shared_ptr_traits::is_const_ref, + "cannot cast from 'const shared_ptr&' to " + "'shared_ptr'"); static_assert( - std::is_class::polymorphic_type>::value); + std::is_class< + typename shared_ptr_traits::polymorphic_type>::value); } template static auto cast(argument_type obj, static_cast_) { check_cast(); - return std::static_pointer_cast::polymorphic_type>(obj); + return std::static_pointer_cast< + typename shared_ptr_traits::polymorphic_type>(obj); } template static auto cast(argument_type obj, dynamic_cast_) { check_cast(); - return std::dynamic_pointer_cast::polymorphic_type>(obj); + return std::dynamic_pointer_cast< + typename shared_ptr_traits::polymorphic_type>(obj); } }; template -struct virtual_traits< virtual_< const std::shared_ptr& > > { +struct virtual_traits&>> { using polymorphic_type = std::remove_cv_t; using argument_type = const std::shared_ptr&; using resolve_type = const std::shared_ptr&; @@ -529,30 +551,32 @@ struct virtual_traits< virtual_< const std::shared_ptr& > > { static_assert(std::is_class::value); static_assert(std::is_polymorphic::value); - static auto key(resolve_type arg) { - return &typeid(*arg); - } + static auto key(resolve_type arg) { return &typeid(*arg); } template static void check_cast() { static_assert(shared_ptr_traits::is_shared_ptr); static_assert( - shared_ptr_traits::is_const_ref, - "cannot cast from 'const shared_ptr&' to 'shared_ptr'"); + shared_ptr_traits::is_const_ref, + "cannot cast from 'const shared_ptr&' to " + "'shared_ptr'"); static_assert( - std::is_class::polymorphic_type>::value); + std::is_class< + typename shared_ptr_traits::polymorphic_type>::value); } template static auto cast(argument_type obj, static_cast_) { check_cast(); - return std::static_pointer_cast::polymorphic_type>(obj); + return std::static_pointer_cast< + typename shared_ptr_traits::polymorphic_type>(obj); } template static auto cast(argument_type obj, dynamic_cast_) { check_cast(); - return std::dynamic_pointer_cast::polymorphic_type>(obj); + return std::dynamic_pointer_cast< + typename shared_ptr_traits::polymorphic_type>(obj); } }; @@ -574,7 +598,8 @@ struct class_info { const char* name; std::unordered_set ti_ptrs; - template static class_info& get(); + template + static class_info& get(); }; template @@ -591,15 +616,14 @@ struct init_class_info { if (!refs++) { info.name = YOMM2_TRACE_ELSE(name, typeid(CLASS).name()); registry::get().classes.push_back(&info); - info.direct_bases = { &class_info::get()... }; + info.direct_bases = {&class_info::get()...}; } auto inserted = info.ti_ptrs.insert(&typeid(CLASS)); if (inserted.second) YOMM2_TRACE( ::yorel::yomm2::detail::log() - << "Register class " << name - << " with &typeid " << &typeid(CLASS) - << "\n"); + << "Register class " << name << " with &typeid " + << &typeid(CLASS) << "\n"); } ~init_class_info() { @@ -609,9 +633,8 @@ struct init_class_info { if (iter != info.ti_ptrs.end()) { YOMM2_TRACE( ::yorel::yomm2::detail::log() - << "Un-register " << info.name - << " with &typeid " << &typeid(CLASS) - << "\n"); + << "Un-register " << info.name << " with &typeid " + << &typeid(CLASS) << "\n"); info.ti_ptrs.erase(iter); } @@ -641,7 +664,7 @@ struct method_info { std::vector specs; void* ambiguous; void* not_implemented; - //const word** slots_strides_p{nullptr}; + // const word** slots_strides_p{nullptr}; word* slots_strides_p{nullptr}; const std::type_info* hash_factors_placement; }; @@ -649,8 +672,8 @@ struct method_info { template struct select_cast { using type = std::conditional_t< - boost::is_virtual_base_of::value, dynamic_cast_, static_cast_ - >; + boost::is_virtual_base_of::value, dynamic_cast_, + static_cast_>; }; template @@ -669,7 +692,8 @@ struct for_each_vp { template struct for_spec { static void collect_class_info(std::vector& vp) { - for_each_vp::template for_spec::collect_class_info(vp); + for_each_vp::template for_spec< + SPEC_REST...>::collect_class_info(vp); } }; @@ -680,8 +704,7 @@ template struct for_each_vp, REST...> { static void collect_class_info(std::vector& vp) { - vp.push_back( - &class_info::get>>()); + vp.push_back(&class_info::get>>()); for_each_vp::collect_class_info(vp); } @@ -690,7 +713,8 @@ struct for_each_vp, REST...> { static void collect_class_info(std::vector& vp) { vp.push_back( &class_info::get>>()); - for_each_vp::template for_spec::collect_class_info(vp); + for_each_vp::template for_spec< + SPEC_REST...>::collect_class_info(vp); } }; @@ -700,13 +724,11 @@ struct for_each_vp, REST...> { template struct for_each_vp { - static void collect_class_info(std::vector& vp) { - } + static void collect_class_info(std::vector& vp) {} template struct for_spec { - static void collect_class_info(std::vector& vp) { - } + static void collect_class_info(std::vector& vp) {} }; enum { count = 0 }; @@ -716,25 +738,18 @@ template struct resolver; template -struct resolver<1, FIRST, REST...> -{ +struct resolver<1, FIRST, REST...> { static void* resolve( - const word* hash_table, - std::uintptr_t hash_mult, - std::size_t hash_shift, - word ss, - resolve_arg_t first, + const word* hash_table, std::uintptr_t hash_mult, + std::size_t hash_shift, word ss, resolve_arg_t first, resolve_arg_t... rest) { return resolver<1, REST...>::resolve( hash_table, hash_mult, hash_shift, ss, rest...); } static void* resolve( - const word* hash_table, - std::uintptr_t hash_mult, - std::size_t hash_shift, - const word* ssp, - resolve_arg_t first, + const word* hash_table, std::uintptr_t hash_mult, + std::size_t hash_shift, const word* ssp, resolve_arg_t first, resolve_arg_t... rest) { return resolver<1, REST...>::resolve( hash_table, hash_mult, hash_shift, ssp, rest...); @@ -742,19 +757,15 @@ struct resolver<1, FIRST, REST...> }; template -struct resolver<1, virtual_, REST...> -{ +struct resolver<1, virtual_, REST...> { static void* resolve( - const word* hash_table, - std::uintptr_t hash_mult, - std::size_t hash_shift, - word ss, - resolve_arg_t first, + const word* hash_table, std::uintptr_t hash_mult, + std::size_t hash_shift, word ss, resolve_arg_t first, resolve_arg_t... rest) { auto key = virtual_traits>::key(first); YOMM2_TRACE( - detail::log() << "hash_table = " << hash_table - << " slot = " << ss.i << " key = " << key); + detail::log() << "hash_table = " << hash_table << " slot = " << ss.i + << " key = " << key); auto mptr = detail::get_mptr(hash_table, hash_mult, hash_shift, key); YOMM2_TRACE(detail::log() << " mptr = " << mptr); auto pf = mptr[ss.i].pf; @@ -763,16 +774,13 @@ struct resolver<1, virtual_, REST...> } static void* resolve( - const word* hash_table, - std::uintptr_t hash_mult, - std::size_t hash_shift, - const word* ssp, - resolve_arg_t first, + const word* hash_table, std::uintptr_t hash_mult, + std::size_t hash_shift, const word* ssp, resolve_arg_t first, resolve_arg_t... rest) { auto key = virtual_traits>::key(first); YOMM2_TRACE( detail::log() << "hash_table = " << hash_table - << " slot = " << ssp->i << " key = " << key); + << " slot = " << ssp->i << " key = " << key); auto mptr = detail::get_mptr(hash_table, hash_mult, hash_shift, key); YOMM2_TRACE(detail::log() << " mptr = " << mptr); auto pf = mptr[ssp->i].pf; @@ -781,14 +789,9 @@ struct resolver<1, virtual_, REST...> } static void* resolve_next( - const word* hash_table, - std::uintptr_t hash_mult, - std::size_t hash_shift, - const word* ssp, - const word* dispatch, - resolve_arg_t first, - resolve_arg_t... rest) - { + const word* hash_table, std::uintptr_t hash_mult, + std::size_t hash_shift, const word* ssp, const word* dispatch, + resolve_arg_t first, resolve_arg_t... rest) { auto key = virtual_traits>::key(first); YOMM2_TRACE(detail::log() << " key = " << key); auto mptr = detail::get_mptr(hash_table, hash_mult, hash_shift, key); @@ -806,44 +809,30 @@ struct resolver<1, virtual_, REST...> }; template -struct resolver -{ +struct resolver { static void* resolve( - const word* hash_table, - std::uintptr_t hash_mult, - std::size_t hash_shift, - word ss, - resolve_arg_t first, + const word* hash_table, std::uintptr_t hash_mult, + std::size_t hash_shift, word ss, resolve_arg_t first, resolve_arg_t... rest) { return resolver::resolve_first( hash_table, hash_mult, hash_shift, ss, rest...); } static void* resolve_next( - const word* hash_table, - std::uintptr_t hash_mult, - std::size_t hash_shift, - const word* ssp, - const word* dispatch, - resolve_arg_t first, - resolve_arg_t... rest) - { + const word* hash_table, std::uintptr_t hash_mult, + std::size_t hash_shift, const word* ssp, const word* dispatch, + resolve_arg_t first, resolve_arg_t... rest) { return resolver::resolve_next( hash_table, hash_mult, hash_shift, ssp, dispatch, rest...); } }; template -struct resolver, REST...> -{ +struct resolver, REST...> { static void* resolve_first( - const word* hash_table, - std::uintptr_t hash_mult, - std::size_t hash_shift, - const word* ssp, - resolve_arg_t first, - resolve_arg_t... rest) - { + const word* hash_table, std::uintptr_t hash_mult, + std::size_t hash_shift, const word* ssp, resolve_arg_t first, + resolve_arg_t... rest) { auto key = virtual_traits>::key(first); YOMM2_TRACE(detail::log() << " key = " << key); auto mptr = detail::get_mptr(hash_table, hash_mult, hash_shift, key); @@ -857,13 +846,9 @@ struct resolver, REST...> } static void* resolve_first( - const word* hash_table, - std::uintptr_t hash_mult, - std::size_t hash_shift, - word ss, - resolve_arg_t first, - resolve_arg_t... rest) - { + const word* hash_table, std::uintptr_t hash_mult, + std::size_t hash_shift, word ss, resolve_arg_t first, + resolve_arg_t... rest) { auto ssp = ss.pw; auto key = virtual_traits>::key(first); YOMM2_TRACE(detail::log() << " key = " << key); @@ -878,14 +863,9 @@ struct resolver, REST...> } static void* resolve_next( - const word* hash_table, - std::uintptr_t hash_mult, - std::size_t hash_shift, - const word* ssp, - const word* dispatch, - resolve_arg_t first, - resolve_arg_t... rest) - { + const word* hash_table, std::uintptr_t hash_mult, + std::size_t hash_shift, const word* ssp, const word* dispatch, + resolve_arg_t first, resolve_arg_t... rest) { auto key = virtual_traits>::key(first); YOMM2_TRACE(detail::log() << " key = " << key); auto mptr = detail::get_mptr(hash_table, hash_mult, hash_shift, key); @@ -901,25 +881,17 @@ struct resolver, REST...> } static void* resolve( - const word* hash_table, - std::uintptr_t hash_mult, - std::size_t hash_shift, - word ss, - resolve_arg_t first, - resolve_arg_t... rest) - { + const word* hash_table, std::uintptr_t hash_mult, + std::size_t hash_shift, word ss, resolve_arg_t first, + resolve_arg_t... rest) { return resolve_first( hash_table, hash_mult, hash_shift, ss, first, rest...); } static void* resolve( - const word* hash_table, - std::uintptr_t hash_mult, - std::size_t hash_shift, - const word* ssp, - resolve_arg_t first, - resolve_arg_t... rest) - { + const word* hash_table, std::uintptr_t hash_mult, + std::size_t hash_shift, const word* ssp, resolve_arg_t first, + resolve_arg_t... rest) { return resolve_first( hash_table, hash_mult, hash_shift, ssp, first, rest...); } @@ -929,32 +901,26 @@ template struct wrapper; template< - typename BASE_RETURN, - class FUNCTION, - typename... BASE_PARAM, - typename... SPEC_PARAM - > + typename BASE_RETURN, class FUNCTION, typename... BASE_PARAM, + typename... SPEC_PARAM> struct wrapper< - BASE_RETURN, - FUNCTION, - BASE_RETURN(BASE_PARAM...), + BASE_RETURN, FUNCTION, BASE_RETURN(BASE_PARAM...), BASE_RETURN(SPEC_PARAM...)> { static BASE_RETURN call(virtual_arg_t... arg) { - return FUNCTION::yOMM2_body( - virtual_traits::template cast( - std::forward>(arg), - typename select_cast< - virtual_base_t, - virtual_base_t>::type())...); - } + return FUNCTION::yOMM2_body( + virtual_traits::template cast( + std::forward>(arg), + typename select_cast< + virtual_base_t, + virtual_base_t>::type())...); + } }; template struct register_spec; template -struct register_spec -{ +struct register_spec { static spec_info* this_; register_spec(void** next, const char* name) { @@ -965,9 +931,10 @@ struct register_spec YOMM2_TRACE( log() << METHOD::name() << ": add spec " << name << "\n"); si.pf = (void*) wrapper< - RETURN_T, SPEC, typename METHOD::signature_type, RETURN_T(SPEC_ARGS...) - >::call; - METHOD::for_each_vp_t::template for_spec::collect_class_info(si.vp); + RETURN_T, SPEC, typename METHOD::signature_type, + RETURN_T(SPEC_ARGS...)>::call; + METHOD::for_each_vp_t::template for_spec< + SPEC_ARGS...>::collect_class_info(si.vp); METHOD::info().specs.push_back(&si); si.next = next; } @@ -978,8 +945,8 @@ struct register_spec auto iter = std::find(specs.begin(), specs.end(), this_); if (iter != specs.end()) { YOMM2_TRACE( - log() << METHOD::name() << ": remove spec " - << (*iter)->name << "\n"); + log() << METHOD::name() << ": remove spec " << (*iter)->name + << "\n"); specs.erase(iter); } } @@ -1009,19 +976,19 @@ struct method { static function_pointer_type resolve(resolve_arg_t... args) { YOMM2_TRACE(detail::log() << "call " << name() << "\n"); return reinterpret_cast( - resolve( - typename POLICY::hash_factors_placement(), args...)); + resolve(typename POLICY::hash_factors_placement(), args...)); } - static void* resolve(policy::hash_factors_in_globals, resolve_arg_t... args) { + static void* + resolve(policy::hash_factors_in_globals, resolve_arg_t... args) { return resolver::resolve( dispatch_data::instance::_.hash_table, dispatch_data::instance::_.hash.mult, - dispatch_data::instance::_.hash.shift, - slots_strides, args...); + dispatch_data::instance::_.hash.shift, slots_strides, args...); } - static void* resolve(policy::hash_factors_in_vector, resolve_arg_t... args) { + static void* + resolve(policy::hash_factors_in_vector, resolve_arg_t... args) { auto ssp = slots_strides.pw; auto hash_table = ssp++->pw; auto hash_mult = ssp++->ul; @@ -1062,8 +1029,8 @@ struct method { registry::get().methods.push_back(&inf); inf.not_implemented = (void*) not_implemented; inf.ambiguous = (void*) ambiguous; - inf.hash_factors_placement = - &typeid(typename POLICY::hash_factors_placement); + inf.hash_factors_placement + = &typeid(typename POLICY::hash_factors_placement); } } diff --git a/include/yorel/yomm2/runtime.hpp b/include/yorel/yomm2/runtime.hpp index cedafc9d..e00ab688 100644 --- a/include/yorel/yomm2/runtime.hpp +++ b/include/yorel/yomm2/runtime.hpp @@ -25,8 +25,7 @@ namespace detail { struct rt_method; -struct rt_arg -{ +struct rt_arg { rt_method* method; int param; }; @@ -35,8 +34,9 @@ struct rt_class { const class_info* info; std::vector direct_bases; std::vector direct_derived; - std::unordered_set conforming; // all the classes that conform to this one, - // = the class itself and all its subclasses + std::unordered_set + conforming; // all the classes that conform to this one, + // = the class itself and all its subclasses std::vector vp; int next_slot{0}; int first_used_slot{-1}; @@ -46,14 +46,13 @@ struct rt_class { word* mptr; }; -struct rt_spec -{ +struct rt_spec { const spec_info* info; std::vector vp; }; using bitvec = boost::dynamic_bitset<>; -using group_map = std::map< bitvec, std::vector >; +using group_map = std::map>; struct rt_method { method_info* info; @@ -78,8 +77,7 @@ struct runtime { std::vector methods; int class_visit{0}; - struct metrics_t - { + struct metrics_t { size_t method_table_size, dispatch_table_size, hash_table_size; int hash_search_attempts; std::chrono::duration hash_search_time; @@ -106,10 +104,10 @@ struct runtime { void optimize(); static void find_hash_function( - const std::vector& classes, - hash_function& hash, + const std::vector& classes, hash_function& hash, metrics_t& metrics); - static std::vector best(std::vector& candidates); + static std::vector + best(std::vector& candidates); static bool is_more_specific(const rt_spec* a, const rt_spec* b); static bool is_base(const rt_spec* a, const rt_spec* b); }; diff --git a/src/yomm2.cpp b/src/yomm2.cpp index 70d2e8d1..85dc0d5d 100644 --- a/src/yomm2.cpp +++ b/src/yomm2.cpp @@ -3,30 +3,30 @@ // See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) -#include // for max, transform, copy -#include // for assert -#include // for operator-, duration -#include // for uintptr_t -#include // for abort, getenv -#include // for operator<<, setw -#include // for operator<<, ostream -#include // for back_insert_iterator -#include // for list, _List_iterator -#include // for map -#include // for allocator_traits<... -#include // for default_random_en... -#include // for runtime_error -#include // for char_traits, allo... -#include // for type_info -#include // for _Node_iterator -#include // for unordered_set<>::... -#include // for pair -#include // for vector, vector<>:... - -#include // for operator<<, dynam... - -#include // for word, YOMM2_TRACE -#include // for rt_class, runtime +#include // for max, transform, copy +#include // for assert +#include // for operator-, duration +#include // for uintptr_t +#include // for abort, getenv +#include // for operator<<, setw +#include // for operator<<, ostream +#include // for back_insert_iterator +#include // for list, _List_iterator +#include // for map +#include // for allocator_traits<... +#include // for default_random_en... +#include // for runtime_error +#include // for char_traits, allo... +#include // for type_info +#include // for _Node_iterator +#include // for unordered_set<>::... +#include // for pair +#include // for vector, vector<>:... + +#include // for operator<<, dynam... + +#include // for word, YOMM2_TRACE +#include // for rt_class, runtime namespace yorel { namespace yomm2 { @@ -38,21 +38,20 @@ namespace detail { #if YOMM2_ENABLE_TRACE struct indent { - explicit indent(int n) : n(n) { - assert(n >= 0); - } + explicit indent(int n) : n(n) { assert(n >= 0); } int n; }; -std::ostream& operator <<(std::ostream& os, const indent& i) { - for (int n = i.n; n--; ) os << " "; +std::ostream& operator<<(std::ostream& os, const indent& i) { + for (int n = i.n; n--;) + os << " "; return os; } template struct outseq_t { outseq_t(ITER first, ITER last, FUN fun, int indent = 0) - : first(first), last(last), fun(fun), indent(indent) { } + : first(first), last(last), fun(fun), indent(indent) {} ITER first, last; FUN fun; int indent; @@ -60,11 +59,11 @@ struct outseq_t { template outseq_t outseq(ITER first, ITER last, FUN fun) { - return { first, last, fun }; + return {first, last, fun}; } template -std::ostream& operator <<(std::ostream& os, const outseq_t& s) { +std::ostream& operator<<(std::ostream& os, const outseq_t& s) { const char* sep = ""; ITER iter = s.first; os << indent(s.indent); @@ -95,7 +94,8 @@ void runtime::update() { YOMM2_TRACE(log() << "Finished\n"); } -runtime::runtime(const registry& reg, struct dispatch_data& dd) : reg(reg), dd(dd) { +runtime::runtime(const registry& reg, struct dispatch_data& dd) + : reg(reg), dd(dd) { } void runtime::augment_classes() { @@ -120,7 +120,7 @@ void runtime::augment_classes() { if (!rt_base) { throw std::runtime_error( std::string("yomm2: base class of ") - YOMM2_TRACE(+ rt_class.info->name) + YOMM2_TRACE(+rt_class.info->name) + " not registered"); } } @@ -134,10 +134,11 @@ void runtime::augment_classes() { void runtime::augment_methods() { methods.resize(reg.methods.size()); auto meth_info_iter = reg.methods.begin(), - meth_info_iter_end = reg.methods.end(); + meth_info_iter_end = reg.methods.end(); auto meth_iter = methods.begin(); - for (; meth_info_iter != meth_info_iter_end; ++meth_info_iter, ++meth_iter) { + for (; meth_info_iter != meth_info_iter_end; + ++meth_info_iter, ++meth_iter) { meth_iter->info = *meth_info_iter; meth_iter->vp.resize((*meth_info_iter)->vp.size()); int param_index = 0; @@ -148,20 +149,19 @@ void runtime::augment_methods() { auto rt_class = class_map[ci]; if (!rt_class) { YOMM2_TRACE( - std::cerr << meth_iter->info->name - << " parameter " << (param_index + 1) - << ": "); + std::cerr << meth_iter->info->name << " parameter " + << (param_index + 1) << ": "); std::cerr << "\nUnregistered class\n"; abort(); } - rt_arg param = { &*meth_iter, param_index++ }; + rt_arg param = {&*meth_iter, param_index++}; rt_class->vp.push_back(param); return class_map[ci]; }); meth_iter->specs.resize((*meth_info_iter)->specs.size()); auto spec_info_iter = (*meth_info_iter)->specs.begin(), - spec_info_end = (*meth_info_iter)->specs.end(); + spec_info_end = (*meth_info_iter)->specs.end(); auto spec_iter = meth_iter->specs.begin(); for (; spec_info_iter != spec_info_end; ++spec_info_iter, ++spec_iter) { @@ -171,13 +171,14 @@ void runtime::augment_methods() { std::transform( (*spec_info_iter)->vp.begin(), (*spec_info_iter)->vp.end(), spec_iter->vp.begin(), - [this, meth_iter, spec_iter, ¶m_index](const class_info* ci) { + [this, meth_iter, spec_iter, + ¶m_index](const class_info* ci) { auto rt_class = class_map[ci]; if (!rt_class) { YOMM2_TRACE( - std::cerr << meth_iter->info->name - << ": spec " << spec_iter->info->name - << ": parameter " << (param_index + 1) << ": "); + std::cerr << meth_iter->info->name << ": spec " + << spec_iter->info->name << ": parameter " + << (param_index + 1) << ": "); std::cerr << "\nUnregistered class\n"; abort(); } @@ -201,7 +202,7 @@ void runtime::layer_classes() { for (int layer = 1; !input.empty(); ++layer) { YOMM2_TRACE(const char* sep = ""); - for (auto class_iter = input.begin(); class_iter != input.end(); ) { + for (auto class_iter = input.begin(); class_iter != input.end();) { auto seen_all_bases = true; auto in_this_layer = (*class_iter)->direct_bases.empty(); @@ -234,8 +235,7 @@ void runtime::layer_classes() { void runtime::calculate_conforming_classes() { for (auto class_iter = layered_classes.rbegin(); - class_iter != layered_classes.rend(); - ++class_iter) { + class_iter != layered_classes.rend(); ++class_iter) { auto c = *class_iter; c->conforming.insert(c); for (auto s : c->direct_derived) { @@ -259,10 +259,8 @@ void runtime::allocate_slots() { int slot = c.next_slot++; YOMM2_TRACE( - log() - << " for " << mp.method->info->name << "#" << mp.param - << ": " - << slot << " also in"); + log() << " for " << mp.method->info->name << "#" << mp.param + << ": " << slot << " also in"); if (mp.method->slots.size() <= mp.param) { mp.method->slots.resize(mp.param + 1); @@ -357,18 +355,14 @@ void runtime::build_dispatch_tables() { for (auto vp : m.vp) { auto& dim_group = groups[dim]; - YOMM2_TRACE(log() - << indent(1) - << "make groups for param #" << dim - << ", class " << vp->info->name - << "\n"); - - for (auto conforming : vp->conforming) { - YOMM2_TRACE(log() - << indent(2) - << "specs applicable to " - << conforming->info->name - << "\n"); + YOMM2_TRACE( + log() << indent(1) << "make groups for param #" << dim + << ", class " << vp->info->name << "\n"); + + for (auto conforming : vp->conforming) { + YOMM2_TRACE( + log() << indent(2) << "specs applicable to " + << conforming->info->name << "\n"); bitvec mask; mask.resize(m.specs.size()); @@ -377,9 +371,8 @@ void runtime::build_dispatch_tables() { for (auto& spec : m.specs) { if (spec.vp[dim]->conforming.find(conforming) != spec.vp[dim]->conforming.end()) { - YOMM2_TRACE(log() - << indent(3) - << spec.info->name << "\n"); + YOMM2_TRACE( + log() << indent(3) << spec.info->name << "\n"); mask[spec_index] = 1; } ++spec_index; @@ -388,11 +381,12 @@ void runtime::build_dispatch_tables() { dim_group[mask].push_back(conforming); YOMM2_TRACE( - log() << " bit mask = " << mask - // << " group = " - // << std::distance(dim_group.begin(), dim_group.find(mask)) - << "\n"); - + log() << " bit mask = " + << mask + // << " group = " + // << std::distance(dim_group.begin(), + // dim_group.find(mask)) + << "\n"); } ++dim; @@ -406,8 +400,8 @@ void runtime::build_dispatch_tables() { for (int dim = 1; dim < m.vp.size(); ++dim) { stride *= groups[dim - 1].size(); YOMM2_TRACE( - log() << " stride for dim " << dim - << " = " << stride << "\n"); + log() << " stride for dim " << dim << " = " << stride + << "\n"); m.strides.push_back(stride); } } @@ -415,7 +409,8 @@ void runtime::build_dispatch_tables() { m.first_dim = groups[0]; for (int dim = 0; dim < m.vp.size(); ++dim) { - YOMM2_TRACE(log()<< indent(1) << "groups for dim " << dim << ":\n"); + YOMM2_TRACE( + log() << indent(1) << "groups for dim " << dim << ":\n"); int group_num = 0; for (auto& group_pair : groups[dim]) { auto& group = group_pair.second; @@ -424,14 +419,15 @@ void runtime::build_dispatch_tables() { } #if YOMM2_ENABLE_TRACE { - auto mask = group_pair.first; - log() - << indent(2) - << "group " << dim << "/" << group_num << " mask " << mask - << " " << outseq( - group.begin(), group.end(), - [](const rt_class* c) { return c->info->name; }) - << "\n"; + auto mask = group_pair.first; + log() << indent(2) << "group " << dim << "/" << group_num + << " mask " << mask << " " + << outseq( + group.begin(), group.end(), + [](const rt_class* c) { + return c->info->name; + }) + << "\n"; } #endif ++group_num; @@ -450,35 +446,31 @@ void runtime::build_dispatch_tables() { std::vector specs; std::transform( - m.specs.begin(), m.specs.end(), - std::back_inserter(specs), + m.specs.begin(), m.specs.end(), std::back_inserter(specs), [](const rt_spec& spec) { return &spec; }); for (auto& spec : m.specs) { - YOMM2_TRACE(log() << indent(2) << spec.info->name << ":\n"); + YOMM2_TRACE(log() << indent(2) << spec.info->name << ":\n"); std::vector candidates; std::copy_if( - specs.begin(), specs.end(), - std::back_inserter(candidates), + specs.begin(), specs.end(), std::back_inserter(candidates), [spec](const rt_spec* other) { return is_base(other, &spec); }); #if YOMM2_ENABLE_TRACE - log() - << indent(3) - << "select best of:\n"; + log() << indent(3) << "select best of:\n"; for (auto& candidate : candidates) { - log() << indent(4) - << candidate->info->name << "\n"; + log() << indent(4) << candidate->info->name << "\n"; } #endif auto nexts = best(candidates); if (nexts.size() == 1) { auto next = nexts.front()->info; - YOMM2_TRACE(log() << indent(3) << "-> " << next->name << "\n"); + YOMM2_TRACE( + log() << indent(3) << "-> " << next->name << "\n"); *spec.info->next = next->pf; } else if (nexts.empty()) { YOMM2_TRACE(log() << indent(3) << "-> none\n"); @@ -503,14 +495,12 @@ void runtime::build_dispatch_table( auto& group = group_pair.second; #if YOMM2_ENABLE_TRACE - log() - << indent(m.vp.size() - dim + 1) - << "group " << dim << "/" << group_index - << " mask " << mask - << " " << outseq( - group.begin(), group.end(), - [](const rt_class* c) { return c->info->name; }) - << "\n"; + log() << indent(m.vp.size() - dim + 1) << "group " << dim << "/" + << group_index << " mask " << mask << " " + << outseq( + group.begin(), group.end(), + [](const rt_class* c) { return c->info->name; }) + << "\n"; #endif if (dim == 0) { std::vector applicable; @@ -525,34 +515,35 @@ void runtime::build_dispatch_table( } #if YOMM2_ENABLE_TRACE - log() - << indent(m.vp.size() - dim + 2) - << "select best of:\n"; + log() << indent(m.vp.size() - dim + 2) << "select best of:\n"; for (auto& app : applicable) { - log() << indent(m.vp.size() - dim + 3) - << app->info->name << "\n"; + log() << indent(m.vp.size() - dim + 3) << app->info->name + << "\n"; } #endif auto specs = best(applicable); if (specs.size() > 1) { - YOMM2_TRACE(log() << indent(m.vp.size() - dim + 2) << "ambiguous\n"); + YOMM2_TRACE( + log() << indent(m.vp.size() - dim + 2) << "ambiguous\n"); m.dispatch_table.push_back(m.info->ambiguous); } else if (specs.empty()) { - YOMM2_TRACE(log() << indent(m.vp.size() - dim + 2) << "not implemented\n"); + YOMM2_TRACE( + log() << indent(m.vp.size() - dim + 2) + << "not implemented\n"); m.dispatch_table.push_back(m.info->not_implemented); } else { m.dispatch_table.push_back(specs[0]->info->pf); #if YOMM2_ENABLE_TRACE - log() - << indent(m.vp.size() - dim + 2) - << outseq( - specs.begin(), specs.end(), - [](const rt_spec* spec) { return spec->info->name; }) - << ": pf = " << specs[0]->info->pf - << "\n"; + log() << indent(m.vp.size() - dim + 2) + << outseq( + specs.begin(), specs.end(), + [](const rt_spec* spec) { + return spec->info->name; + }) + << ": pf = " << specs[0]->info->pf << "\n"; #endif } } else { @@ -560,13 +551,11 @@ void runtime::build_dispatch_table( } ++group_index; } - } void runtime::find_hash_function( - const std::vector& classes, - hash_function& hash, - metrics_t& metrics) { + const std::vector& classes, hash_function& hash, + metrics_t& metrics) { std::vector keys; auto start_time = std::chrono::steady_clock::now(); @@ -584,7 +573,7 @@ void runtime::find_hash_function( int total_attempts = 0; int M = 1; - for (auto size = N * 5 / 4; size >>= 1; ) { + for (auto size = N * 5 / 4; size >>= 1;) { ++M; } @@ -596,8 +585,8 @@ void runtime::find_hash_function( auto hash_size = 1 << M; YOMM2_TRACE( - log() << indent(1) << "trying with M = " << M - << ", " << hash_size << " buckets\n"); + log() << indent(1) << "trying with M = " << M << ", " << hash_size + << " buckets\n"); bool found = false; int attempts = 0; @@ -621,14 +610,15 @@ void runtime::find_hash_function( } metrics.hash_search_attempts = total_attempts; - metrics.hash_search_time = std::chrono::steady_clock::now() - start_time; + metrics.hash_search_time + = std::chrono::steady_clock::now() - start_time; metrics.hash_table_size = hash_size; if (found) { YOMM2_TRACE( - log() << indent(1) << "found " << hash.mult - << " after " << total_attempts << " attempts and " - << metrics.hash_search_time.count() * 1000 << " msecs\n"); + log() << indent(1) << "found " << hash.mult << " after " + << total_attempts << " attempts and " + << metrics.hash_search_time.count() * 1000 << " msecs\n"); return; } } @@ -636,7 +626,7 @@ void runtime::find_hash_function( throw std::runtime_error("cannot find hash factor"); } -void operator +=(std::vector& words, const std::vector& ints) { +void operator+=(std::vector& words, const std::vector& ints) { words.reserve(words.size() + ints.size()); for (auto i : ints) { word w; @@ -668,14 +658,11 @@ void runtime::install_gv() { for (int pass = 0; pass != 2; ++pass) { dd.gv.resize(0); - YOMM2_TRACE( - if (pass) { - log() - << "Initializing global vector at " << dd.gv.data() << "\n" - << std::setw(4) << dd.gv.size() - << " pointer to control table\n"; - } - ); + YOMM2_TRACE(if (pass) { + log() << "Initializing global vector at " << dd.gv.data() << "\n" + << std::setw(4) << dd.gv.size() + << " pointer to control table\n"; + }); // reserve a work for control table dd.gv.emplace_back(make_word(nullptr)); @@ -684,30 +671,25 @@ void runtime::install_gv() { dd.hash_table = hash_table; YOMM2_TRACE( - if (pass) - log() - << std::setw(4) << dd.gv.size() - << " hash table\n"); + if (pass) log() << std::setw(4) << dd.gv.size() << " hash table\n"); dd.gv.resize(dd.gv.size() + metrics.hash_table_size); YOMM2_TRACE( - if (pass) - log() - << std::setw(4) << dd.gv.size() - << " control table\n"); + if (pass) log() + << std::setw(4) << dd.gv.size() << " control table\n"); dd.gv.resize(dd.gv.size() + metrics.hash_table_size); for (auto& m : methods) { YOMM2_TRACE( - if (pass) - log() << std::setw(4) << dd.gv.size() - << ' ' << m.info->name << "\n"); + if (pass) log() + << std::setw(4) << dd.gv.size() << ' ' << m.info->name << "\n"); m.info->slots_strides_p->pw = dd.gv.data() + dd.gv.size(); - if (*m.info->hash_factors_placement == typeid(policy::hash_factors_in_vector)) { + if (*m.info->hash_factors_placement + == typeid(policy::hash_factors_in_vector)) { dd.gv.emplace_back(make_word(hash_table)); dd.gv.emplace_back(make_word(dd.hash.mult)); dd.gv.emplace_back(make_word(dd.hash.shift)); @@ -728,14 +710,13 @@ void runtime::install_gv() { dd.gv.emplace_back(make_word(*stride_iter++)); } YOMM2_TRACE( - if (pass) - log() << std::setw(4) << dd.gv.size() - << ' ' << m.info->name << " dispatch table\n"); + if (pass) log() << std::setw(4) << dd.gv.size() << ' ' + << m.info->name << " dispatch table\n"); m.gv_dispatch_table = dd.gv.data() + dd.gv.size(); std::transform( m.dispatch_table.begin(), m.dispatch_table.end(), - std::back_inserter(dd.gv), [](void* pf) { - return make_word(pf); }); + std::back_inserter(dd.gv), + [](void* pf) { return make_word(pf); }); } auto control_table = hash_table + metrics.hash_table_size; @@ -744,15 +725,13 @@ void runtime::install_gv() { for (auto& cls : classes) { cls.mptr = dd.gv.data() + dd.gv.size() - cls.first_used_slot; YOMM2_TRACE( - if (pass) - log() << std::setw(4) << dd.gv.size() - << " mtbl for " << cls.info->name - << ": " << cls.mptr << "\n"); + if (pass) log() << std::setw(4) << dd.gv.size() << " mtbl for " + << cls.info->name << ": " << cls.mptr << "\n"); if (cls.first_used_slot != -1) { std::transform( cls.mtbl.begin() + cls.first_used_slot, cls.mtbl.end(), - std::back_inserter(dd.gv), [](int i) { - return make_word(i); }); + std::back_inserter(dd.gv), + [](int i) { return make_word(i); }); } if (pass) { for (auto tid : cls.info->ti_ptrs) { @@ -771,40 +750,37 @@ void runtime::optimize() { YOMM2_TRACE(log() << "Optimizing\n"); for (auto& m : methods) { - YOMM2_TRACE( - log() << " " - << m.info->name - << "\n"); + YOMM2_TRACE(log() << " " << m.info->name << "\n"); auto slot = m.slots[0]; if (m.vp.size() == 1) { for (auto cls : m.vp[0]->conforming) { auto pf = m.dispatch_table[cls->mptr[slot].i]; YOMM2_TRACE( - log() << " " << cls->info->name - << ".mtbl[" << slot << "] = " << pf << " (function)" - << "\n"); + log() << " " << cls->info->name << ".mtbl[" << slot + << "] = " << pf << " (function)" + << "\n"); cls->mptr[slot].pf = pf; } } else { for (auto cls : m.vp[0]->conforming) { auto pw = m.gv_dispatch_table + cls->mptr[slot].i; YOMM2_TRACE( - log() << " " << cls->info->name - << ".mtbl[" << slot << "] = gv+" << (pw - dd.hash_table) - << "\n"); + log() << " " << cls->info->name << ".mtbl[" << slot + << "] = gv+" << (pw - dd.hash_table) << "\n"); cls->mptr[slot].pw = pw; } } } } -std::vector runtime::best(std::vector& candidates) { +std::vector +runtime::best(std::vector& candidates) { std::vector best; for (auto spec : candidates) { const rt_spec* candidate = spec; - for (auto iter = best.begin(); iter != best.end(); ) { + for (auto iter = best.begin(); iter != best.end();) { if (is_more_specific(spec, *iter)) { iter = best.erase(iter); } else if (is_more_specific(*iter, spec)) { @@ -823,17 +799,19 @@ std::vector runtime::best(std::vector& candidate return best; } -bool runtime::is_more_specific(const rt_spec* a, const rt_spec* b) -{ +bool runtime::is_more_specific(const rt_spec* a, const rt_spec* b) { bool result = false; auto a_iter = a->vp.begin(), a_last = a->vp.end(), b_iter = b->vp.begin(); for (; a_iter != a_last; ++a_iter, ++b_iter) { if (*a_iter != *b_iter) { - if ((*b_iter)->conforming.find(*a_iter) != (*b_iter)->conforming.end()) { + if ((*b_iter)->conforming.find(*a_iter) + != (*b_iter)->conforming.end()) { result = true; - } else if ((*a_iter)->conforming.find(*b_iter) != (*a_iter)->conforming.end()) { + } else if ( + (*a_iter)->conforming.find(*b_iter) + != (*a_iter)->conforming.end()) { return false; } } @@ -842,15 +820,15 @@ bool runtime::is_more_specific(const rt_spec* a, const rt_spec* b) return result; } -bool runtime::is_base(const rt_spec* a, const rt_spec* b) -{ +bool runtime::is_base(const rt_spec* a, const rt_spec* b) { bool result = false; auto a_iter = a->vp.begin(), a_last = a->vp.end(), b_iter = b->vp.begin(); for (; a_iter != a_last; ++a_iter, ++b_iter) { if (*a_iter != *b_iter) { - if ((*a_iter)->conforming.find(*b_iter) == (*a_iter)->conforming.end()) { + if ((*a_iter)->conforming.find(*b_iter) + == (*a_iter)->conforming.end()) { return false; } else { result = true; @@ -865,9 +843,7 @@ std::ostream* active_log = nullptr; std::ostream& log() { static struct null_streambuf : std::streambuf { - int_type overflow(int_type c) override { - return 0; - } + int_type overflow(int_type c) override { return 0; } } null; static std::ostream discard_log(&null); @@ -893,8 +869,9 @@ std::ostream* log_off() { void default_method_call_error_handler(const method_call_error& error) { #if YOMM2_ENABLE_TRACE - const char* explanation[] = { "no applicable definition", "ambiguous call" }; - std::cerr << explanation[error.code] << "while calling " << error.method_name << "\n"; + const char* explanation[] = {"no applicable definition", "ambiguous call"}; + std::cerr << explanation[error.code] << "while calling " + << error.method_name << "\n"; #endif abort(); } @@ -906,14 +883,16 @@ void unregistered_class_error(const std::type_info* pt) { abort(); } - } // namespace detail void update_methods() { - update_methods(detail::registry::get(), detail::dispatch_data::instance::_); + update_methods( + detail::registry::get(), + detail::dispatch_data::instance::_); } -method_call_error_handler set_method_call_error_handler(method_call_error_handler handler) { +method_call_error_handler +set_method_call_error_handler(method_call_error_handler handler) { auto prev = detail::call_error_handler; detail::call_error_handler = handler; return prev;