diff --git a/.clang-format b/.clang-format index c77d678..8fe3b32 100644 --- a/.clang-format +++ b/.clang-format @@ -1,35 +1,42 @@ -Language: Json -ColumnLimit: 1000 -IndentWidth: 4 ---- +# https://clang.llvm.org/docs/ClangFormatStyleOptions.html +# for clang-format 17.0.1 Language: Cpp -AccessModifierOffset: -4 -AlignAfterOpenBracket: Align +BasedOnStyle: 'WebKit' +# AccessModifierOffset: 2 +AlignAfterOpenBracket: 'AlwaysBreak' AlignArrayOfStructures: None -AlignConsecutiveMacros: None AlignConsecutiveAssignments: None AlignConsecutiveBitFields: None AlignConsecutiveDeclarations: None +AlignConsecutiveMacros: None +# AlignConsecutiveShortCaseStatements: None AlignEscapedNewlines: Left AlignOperands: Align -AlignTrailingComments: true +AlignTrailingComments: + Kind: Always + OverEmptyLines: 1 AllowAllArgumentsOnNextLine: true AllowAllParametersOfDeclarationOnNextLine: true -AllowShortEnumsOnASingleLine: false -AllowShortBlocksOnASingleLine: Empty +AllowShortBlocksOnASingleLine: Never AllowShortCaseLabelsOnASingleLine: false -AllowShortFunctionsOnASingleLine: Inline -AllowShortLambdasOnASingleLine: All -AllowShortIfStatementsOnASingleLine: WithoutElse +# AllowShortCompoundRequirementOnASingleLine: true +AllowShortEnumsOnASingleLine: false +AllowShortFunctionsOnASingleLine: InlineOnly +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: Inline AllowShortLoopsOnASingleLine: false AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: false -AlwaysBreakTemplateDeclarations: true -AttributeMacros: - - __capability -BinPackArguments: true -BinPackParameters: true +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: Yes +# AttributeMacros: +# - __pragma +# - _Pragma +# - __attribute__ +# - __declspec +BinPackArguments: false +BinPackParameters: false +BitFieldColonSpacing: After BraceWrapping: AfterCaseLabel: false AfterClass: true @@ -37,159 +44,147 @@ BraceWrapping: AfterEnum: true AfterFunction: true AfterNamespace: true - AfterObjCDeclaration: true + # AfterObjCDeclaration: true AfterStruct: true - AfterUnion: false + AfterUnion: true AfterExternBlock: true BeforeCatch: true BeforeElse: true BeforeLambdaBody: false BeforeWhile: false IndentBraces: false - SplitEmptyFunction: false - SplitEmptyRecord: false - SplitEmptyNamespace: false -BreakBeforeBinaryOperators: None -BreakBeforeConceptDeclarations: true + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +# BracedInitializerIndentWidth: 4 +BreakAfterAttributes: Never +BreakAfterJavaFieldAnnotations: true +BreakArrays: true +BreakBeforeBinaryOperators: NonAssignment BreakBeforeBraces: Custom -BreakBeforeInheritanceComma: false -BreakInheritanceList: BeforeColon +BreakBeforeConceptDeclarations: Always +BreakBeforeInlineASMColon: OnlyMultiline BreakBeforeTernaryOperators: true -BreakConstructorInitializersBeforeComma: false -BreakConstructorInitializers: BeforeColon -BreakAfterJavaFieldAnnotations: false +BreakConstructorInitializers: BeforeComma +BreakInheritanceList: BeforeComma BreakStringLiterals: true -ColumnLimit: 120 -CommentPragmas: '^ IWYU pragma:' -QualifierAlignment: Leave +ColumnLimit: 100 +# CommentPragmas: '^ MEO pragma:' CompactNamespaces: false ConstructorInitializerIndentWidth: 4 ContinuationIndentWidth: 4 Cpp11BracedListStyle: false -DeriveLineEnding: true DerivePointerAlignment: false DisableFormat: false EmptyLineAfterAccessModifier: Never EmptyLineBeforeAccessModifier: LogicalBlock -ExperimentalAutoDetectBinPacking: false -PackConstructorInitializers: BinPack -BasedOnStyle: '' -ConstructorInitializerAllOnOneLineOrOnePerLine: false -AllowAllConstructorInitializersOnNextLine: true +# ExperimentalAutoDetectBinPacking: true FixNamespaceComments: true -ForEachMacros: - - foreach - - Q_FOREACH - - BOOST_FOREACH -IfMacros: - - KJ_IF_MAYBE +# ForEachMacros: +# - foreach +# - Q_FOREACH +# - BOOST_FOREACH +# IfMacros: +# - 'KJ_IF_MAYBE' IncludeBlocks: Preserve -IncludeCategories: - - Regex: '^"(llvm|llvm-c|clang|clang-c)/' - Priority: 2 - SortPriority: 0 - CaseSensitive: false - - Regex: '^(<|"(gtest|gmock|isl|json)/)' - Priority: 3 - SortPriority: 0 - CaseSensitive: false - - Regex: '.*' - Priority: 1 - SortPriority: 0 - CaseSensitive: false -IncludeIsMainRegex: '(Test)?$' -IncludeIsMainSourceRegex: '' +# IncludeCategories: +# IncludeIsMainRegex: +# IncludeIsMainSourceRegex: IndentAccessModifiers: false -IndentCaseLabels: false IndentCaseBlocks: false -IndentGotoLabels: true -IndentPPDirectives: None +IndentCaseLabels: false IndentExternBlock: AfterExternBlock +IndentGotoLabels: false +IndentPPDirectives: None IndentRequiresClause: false IndentWidth: 4 -IndentWrappedFunctionNames: false -InsertTrailingCommas: None -JavaScriptQuotes: Leave -JavaScriptWrapImports: true -KeepEmptyLinesAtTheStartOfBlocks: true +IndentWrappedFunctionNames: true +InsertBraces: true +InsertNewlineAtEOF: true +InsertTrailingCommas: Wrapped +IntegerLiteralSeparator: + Binary: 4 + BinaryMinDigits: 9 + Decimal: 3 + DecimalMinDigits: 7 + Hex: -1 +# JavaImportGroups: +# JavaScriptQuotes: +# JavaScriptWrapImports: +KeepEmptyLinesAtEOF: true +KeepEmptyLinesAtTheStartOfBlocks: false LambdaBodyIndentation: Signature -MacroBlockBegin: '' -MacroBlockEnd: '' +# LineEnding: LF +# MacroBlockBegin: "MAA.*_NS_BEGIN$" +# MacroBlockEnd: "MAA.*_NS_END$" +# Macros: MaxEmptyLinesToKeep: 1 -NamespaceIndentation: Inner -ObjCBinPackProtocolList: Auto -ObjCBlockIndentWidth: 2 -ObjCBreakBeforeNestedBlockParam: true -ObjCSpaceAfterProperty: false -ObjCSpaceBeforeProtocolList: true -PenaltyBreakAssignment: 2 -PenaltyBreakBeforeFirstCallParameter: 19 -PenaltyBreakComment: 300 -PenaltyBreakFirstLessLess: 120 -PenaltyBreakOpenParenthesis: 0 -PenaltyBreakString: 1000 -PenaltyBreakTemplateDeclaration: 10 -PenaltyExcessCharacter: 1000000 -PenaltyReturnTypeOnItsOwnLine: 1000 -PenaltyIndentedWhitespace: 0 +NamespaceIndentation: None +# NamespaceMacros: +# ObjCBinPackProtocolList: +# ObjCBlockIndentWidth: +# ObjCBreakBeforeNestedBlockParam: +# ObjCSpaceAfterProperty: +# ObjCSpaceBeforeProtocolList: +PackConstructorInitializers: Never +# PenaltyBreakAssignment: +# PenaltyBreakBeforeFirstCallParameter: +# PenaltyBreakComment: +# PenaltyBreakFirstLessLess: +# PenaltyBreakOpenParenthesis: +# PenaltyBreakTemplateDeclaration: +# PenaltyExcessCharacter: +# PenaltyIndentedWhitespace: +# PenaltyReturnTypeOnItsOwnLine: PointerAlignment: Left -PPIndentWidth: -1 -ReferenceAlignment: Pointer +QualifierAlignment: Leave +# QualifierOrder: +# - inline +# - static +# - const +# - constexpr +# - type +ReferenceAlignment: Left ReflowComments: true RemoveBracesLLVM: false +RemoveParentheses: Leave +RemoveSemicolon: false RequiresClausePosition: OwnLine +RequiresExpressionIndentation: OuterScope SeparateDefinitionBlocks: Leave -ShortNamespaceLines: 50 +ShortNamespaceLines: 1000 SortIncludes: CaseSensitive -SortJavaStaticImport: Before -SortUsingDeclarations: true +# SortJavaStaticImport: +SortUsingDeclarations: Lexicographic SpaceAfterCStyleCast: false SpaceAfterLogicalNot: false SpaceAfterTemplateKeyword: true +SpaceAroundPointerQualifiers: Default SpaceBeforeAssignmentOperators: true SpaceBeforeCaseColon: false SpaceBeforeCpp11BracedList: true SpaceBeforeCtorInitializerColon: true -SpaceBeforeInheritanceColon: true +SpaceBeforeJsonColon: false SpaceBeforeParens: ControlStatements -SpaceBeforeParensOptions: - AfterControlStatements: true - AfterForeachMacros: true - AfterFunctionDefinitionName: false - AfterFunctionDeclarationName: false - AfterIfMacros: true - AfterOverloadedOperator: false - AfterRequiresInClause: true - AfterRequiresInExpression: true - BeforeNonEmptyParentheses: false -SpaceAroundPointerQualifiers: Default +# SpaceBeforeParensOptions: SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false SpaceInEmptyBlock: false SpaceInEmptyParentheses: false SpacesBeforeTrailingComments: 1 SpacesInAngles: Never -SpacesInConditionalStatement: false SpacesInContainerLiterals: true -SpacesInCStyleCastParentheses: false SpacesInLineCommentPrefix: Minimum: 1 Maximum: -1 -SpacesInParentheses: false +SpacesInParens: Never SpacesInSquareBrackets: false -SpaceBeforeSquareBrackets: false -BitFieldColonSpacing: Both Standard: c++20 -StatementAttributeLikeMacros: - - Q_EMIT -StatementMacros: - - Q_UNUSED - - QT_REQUIRE_VERSION +# StatementAttributeLikeMacros: +# StatementMacros: TabWidth: 4 -UseCRLF: false +# TypeNames: +# TypenameMacros: UseTab: Never -WhitespaceSensitiveMacros: - - STRINGIZE - - PP_STRINGIZE - - BOOST_PP_STRINGIZE - - NS_SWIFT_NAME - - CF_SWIFT_NAME +# VerilogBreakBetweenInstancePorts: +# WhitespaceSensitiveMacros: diff --git a/include/common/array.hpp b/include/common/array.hpp index b693e59..fabc5dc 100644 --- a/include/common/array.hpp +++ b/include/common/array.hpp @@ -37,21 +37,30 @@ class basic_array // explicit basic_array(const basic_value& val); // explicit basic_array(basic_value&& val); - template && - std::is_constructible_v>, - bool> = true> + template < + typename collection_t, + std::enable_if_t< + _utils::is_collection + && std::is_constructible_v>, + bool> = true> basic_array(collection_t arr) : _array_data(std::make_move_iterator(arr.begin()), std::make_move_iterator(arr.end())) - {} - template ::value, bool> = true> - basic_array(const jsonization_t& value) : basic_array(value.to_json()) - {} - template ::value, bool> = true> - basic_array(const jsonization_t& value) : basic_array(ext::jsonization().to_json(value)) - {} + { + } + template < + typename jsonization_t, + std::enable_if_t<_utils::has_to_json_in_member::value, bool> = true> + basic_array(const jsonization_t& value) + : basic_array(value.to_json()) + { + } + template < + typename jsonization_t, + std::enable_if_t<_utils::has_to_json_in_templ_spec::value, bool> = true> + basic_array(const jsonization_t& value) + : basic_array(ext::jsonization().to_json(value)) + { + } ~basic_array() noexcept = default; @@ -61,7 +70,10 @@ class basic_array bool exists(size_t pos) const { return contains(pos); } const basic_value& at(size_t pos) const; - string_t dumps(std::optional indent = std::nullopt) const { return indent ? format(*indent) : to_string(); } + string_t dumps(std::optional indent = std::nullopt) const + { + return indent ? format(*indent) : to_string(); + } string_t to_string() const; string_t format(size_t indent = 4) const { return format(indent, 0); } template @@ -112,7 +124,9 @@ class basic_array basic_array& operator=(const basic_array&) = default; basic_array& operator=(basic_array&&) noexcept = default; - template >, bool> = true> + template < + typename value_t, + std::enable_if_t>, bool> = true> basic_array& operator=(value_t rhs) { return *this = basic_array(std::move(rhs)); @@ -121,14 +135,18 @@ class basic_array bool operator==(const basic_array& rhs) const; bool operator!=(const basic_array& rhs) const { return !(*this == rhs); } - template typename collection_t = std::vector, - std::enable_if_t<_utils::is_collection>, bool> = true> + template < + typename value_t, + template typename collection_t = std::vector, + std::enable_if_t<_utils::is_collection>, bool> = true> explicit operator collection_t() const { return as_collection(); } - template ::value, bool> = true> + template < + typename jsonization_t, + std::enable_if_t<_utils::has_from_json_in_member::value, bool> = + true> explicit operator jsonization_t() const { jsonization_t dst {}; @@ -137,8 +155,11 @@ class basic_array } return dst; } - template ::value, bool> = true> + template < + typename jsonization_t, + std::enable_if_t< + _utils::has_from_json_in_templ_spec::value, + bool> = true> explicit operator jsonization_t() const { jsonization_t dst {}; @@ -150,8 +171,9 @@ class basic_array private: template - auto get(std::tuple keys_then_default_value, - std::index_sequence) const; + auto + get(std::tuple keys_then_default_value, + std::index_sequence) const; template auto get_helper(const value_t& default_value, size_t pos, rest_keys_t&&... rest) const; template @@ -164,15 +186,20 @@ class basic_array }; template -inline basic_array::basic_array(std::initializer_list init_list) : _array_data(init_list) -{} +inline basic_array::basic_array(std::initializer_list init_list) + : _array_data(init_list) +{ +} template -inline basic_array::basic_array(typename raw_array::size_type size) : _array_data(size) -{} +inline basic_array::basic_array(typename raw_array::size_type size) + : _array_data(size) +{ +} // template -// inline basic_array::basic_array(const basic_value& val) : basic_array(val.as_array()) +// inline basic_array::basic_array(const basic_value& val) : +// basic_array(val.as_array()) //{} // // template @@ -202,8 +229,9 @@ template template inline decltype(auto) basic_array::emplace_back(args_t&&... args) { - static_assert(std::is_constructible_v, - "Parameter can't be used to construct a raw_array::value_type"); + static_assert( + std::is_constructible_v, + "Parameter can't be used to construct a raw_array::value_type"); return _array_data.emplace_back(std::forward(args)...); } @@ -266,18 +294,18 @@ inline bool basic_array::all() const namespace _as_collection_helper { - template - class has_emplace_back - { - template - static auto test(int) -> decltype(std::declval().emplace_back(), std::true_type()); +template +class has_emplace_back +{ + template + static auto test(int) -> decltype(std::declval().emplace_back(), std::true_type()); - template - static std::false_type test(...); + template + static std::false_type test(...); - public: - static constexpr bool value = decltype(test(0))::value; - }; +public: + static constexpr bool value = decltype(test(0))::value; +}; } template @@ -302,27 +330,31 @@ template template inline auto basic_array::get(key_then_default_value_t&&... keys_then_default_value) const { - return get(std::forward_as_tuple(keys_then_default_value...), - std::make_index_sequence {}); + return get( + std::forward_as_tuple(keys_then_default_value...), + std::make_index_sequence {}); } template template -inline auto basic_array::get(std::tuple keys_then_default_value, - std::index_sequence) const +inline auto basic_array::get( + std::tuple keys_then_default_value, + std::index_sequence) const { constexpr unsigned long default_value_index = sizeof...(key_then_default_value_t) - 1; - return get_helper(std::get(keys_then_default_value), - std::get(keys_then_default_value)...); + return get_helper( + std::get(keys_then_default_value), + std::get(keys_then_default_value)...); } template template -inline auto basic_array::get_helper(const value_t& default_value, size_t pos, rest_keys_t&&... rest) const +inline auto basic_array::get_helper( + const value_t& default_value, size_t pos, rest_keys_t&&... rest) const { - constexpr bool is_json = std::is_same_v, value_t> || - std::is_same_v, value_t> || - std::is_same_v, value_t>; + constexpr bool is_json = std::is_same_v, value_t> + || std::is_same_v, value_t> + || std::is_same_v, value_t>; constexpr bool is_string = std::is_constructible_v && !is_json; if (!contains(pos)) { @@ -341,9 +373,9 @@ template template inline auto basic_array::get_helper(const value_t& default_value, size_t pos) const { - constexpr bool is_json = std::is_same_v, value_t> || - std::is_same_v, value_t> || - std::is_same_v, value_t>; + constexpr bool is_json = std::is_same_v, value_t> + || std::is_same_v, value_t> + || std::is_same_v, value_t>; constexpr bool is_string = std::is_constructible_v && !is_json; if (!contains(pos)) { @@ -382,7 +414,8 @@ inline std::optional basic_array::find(size_t pos) const return std::nullopt; } const auto& val = _array_data.at(pos); - return val.template is() ? std::optional(val.template as()) : std::nullopt; + return val.template is() ? std::optional(val.template as()) + : std::nullopt; } template @@ -434,25 +467,29 @@ inline typename basic_array::reverse_iterator basic_array::r } template -inline typename basic_array::const_reverse_iterator basic_array::rbegin() const noexcept +inline typename basic_array::const_reverse_iterator + basic_array::rbegin() const noexcept { return _array_data.rbegin(); } template -inline typename basic_array::const_reverse_iterator basic_array::rend() const noexcept +inline typename basic_array::const_reverse_iterator + basic_array::rend() const noexcept { return _array_data.rend(); } template -inline typename basic_array::const_reverse_iterator basic_array::crbegin() const noexcept +inline typename basic_array::const_reverse_iterator + basic_array::crbegin() const noexcept { return _array_data.crbegin(); } template -inline typename basic_array::const_reverse_iterator basic_array::crend() const noexcept +inline typename basic_array::const_reverse_iterator + basic_array::crend() const noexcept { return _array_data.crend(); } @@ -470,7 +507,8 @@ inline const basic_value& basic_array::operator[](size_t pos } template -inline basic_array basic_array::operator+(const basic_array& rhs) const& +inline basic_array + basic_array::operator+(const basic_array& rhs) const& { basic_array temp = *this; temp._array_data.insert(_array_data.end(), rhs.begin(), rhs.end()); @@ -481,8 +519,10 @@ template inline basic_array basic_array::operator+(basic_array&& rhs) const& { basic_array temp = *this; - temp._array_data.insert(_array_data.end(), std::make_move_iterator(rhs.begin()), - std::make_move_iterator(rhs.end())); + temp._array_data.insert( + _array_data.end(), + std::make_move_iterator(rhs.begin()), + std::make_move_iterator(rhs.end())); return temp; } @@ -496,7 +536,10 @@ inline basic_array basic_array::operator+(const basic_array< template inline basic_array basic_array::operator+(basic_array&& rhs) && { - _array_data.insert(_array_data.end(), std::make_move_iterator(rhs.begin()), std::make_move_iterator(rhs.end())); + _array_data.insert( + _array_data.end(), + std::make_move_iterator(rhs.begin()), + std::make_move_iterator(rhs.end())); return std::move(*this); } @@ -510,7 +553,10 @@ inline basic_array& basic_array::operator+=(const basic_arra template inline basic_array& basic_array::operator+=(basic_array&& rhs) { - _array_data.insert(_array_data.end(), std::make_move_iterator(rhs.begin()), std::make_move_iterator(rhs.end())); + _array_data.insert( + _array_data.end(), + std::make_move_iterator(rhs.begin()), + std::make_move_iterator(rhs.end())); return *this; } @@ -520,11 +566,14 @@ inline bool basic_array::operator==(const basic_array& rhs) return _array_data == rhs._array_data; } -template >, - typename enable_t = - std::enable_if_t || std::is_base_of_v>> +template < + typename ostream_t, + typename string_t, + typename std_ostream_t = std::basic_ostream< + typename string_t::value_type, + std::char_traits>, + typename enable_t = std::enable_if_t< + std::is_same_v || std::is_base_of_v>> ostream_t& operator<<(ostream_t& out, const basic_array& arr) { out << arr.format(); diff --git a/include/common/exception.hpp b/include/common/exception.hpp index 065acbc..016fb64 100644 --- a/include/common/exception.hpp +++ b/include/common/exception.hpp @@ -9,7 +9,10 @@ class exception : public std::exception { public: exception() = default; - exception(const std::string& msg) : _what(msg) {} + exception(const std::string& msg) + : _what(msg) + { + } exception(const exception&) = default; exception& operator=(const exception&) = default; @@ -18,7 +21,10 @@ class exception : public std::exception virtual ~exception() noexcept override = default; - virtual const char* what() const noexcept override { return _what.empty() ? "Unknown exception" : _what.c_str(); } + virtual const char* what() const noexcept override + { + return _what.empty() ? "Unknown exception" : _what.c_str(); + } protected: std::string _what; diff --git a/include/common/object.hpp b/include/common/object.hpp index 56c327b..97c27f2 100644 --- a/include/common/object.hpp +++ b/include/common/object.hpp @@ -36,19 +36,30 @@ class basic_object // explicit basic_object(const basic_value& val); // explicit basic_object(basic_value&& val); - template && - std::is_constructible_v>, - bool> = true> - basic_object(map_t map) : _object_data(std::make_move_iterator(map.begin()), std::make_move_iterator(map.end())) - {} - template ::value, bool> = true> - basic_object(const jsonization_t& value) : basic_object(value.to_json()) - {} - template ::value, bool> = true> - basic_object(const jsonization_t& value) : basic_object(ext::jsonization().to_json(value)) - {} + template < + typename map_t, + std::enable_if_t< + _utils::is_map + && std::is_constructible_v>, + bool> = true> + basic_object(map_t map) + : _object_data(std::make_move_iterator(map.begin()), std::make_move_iterator(map.end())) + { + } + template < + typename jsonization_t, + std::enable_if_t<_utils::has_to_json_in_member::value, bool> = true> + basic_object(const jsonization_t& value) + : basic_object(value.to_json()) + { + } + template < + typename jsonization_t, + std::enable_if_t<_utils::has_to_json_in_templ_spec::value, bool> = true> + basic_object(const jsonization_t& value) + : basic_object(ext::jsonization().to_json(value)) + { + } ~basic_object() = default; @@ -58,7 +69,10 @@ class basic_object bool exists(const string_t& key) const { return contains(key); } const basic_value& at(const string_t& key) const; - string_t dumps(std::optional indent = std::nullopt) const { return indent ? format(*indent) : to_string(); } + string_t dumps(std::optional indent = std::nullopt) const + { + return indent ? format(*indent) : to_string(); + } string_t to_string() const; string_t format(size_t indent = 4) const { return format(indent, 0); } template @@ -102,7 +116,9 @@ class basic_object basic_object& operator=(const basic_object&) = default; basic_object& operator=(basic_object&&) = default; - template >, bool> = true> + template < + typename value_t, + std::enable_if_t>, bool> = true> basic_object& operator=(value_t rhs) { return *this = basic_object(std::move(rhs)); @@ -111,14 +127,18 @@ class basic_object bool operator==(const basic_object& rhs) const; bool operator!=(const basic_object& rhs) const { return !(*this == rhs); } - template typename map_t = std::map, - std::enable_if_t<_utils::is_map>, bool> = true> + template < + typename value_t, + template typename map_t = std::map, + std::enable_if_t<_utils::is_map>, bool> = true> explicit operator map_t() const { return as_map(); } - template ::value, bool> = true> + template < + typename jsonization_t, + std::enable_if_t<_utils::has_from_json_in_member::value, bool> = + true> explicit operator jsonization_t() const { jsonization_t dst {}; @@ -127,8 +147,11 @@ class basic_object } return dst; } - template ::value, bool> = true> + template < + typename jsonization_t, + std::enable_if_t< + _utils::has_from_json_in_templ_spec::value, + bool> = true> explicit operator jsonization_t() const { jsonization_t dst {}; @@ -140,8 +163,9 @@ class basic_object private: template - auto get(std::tuple keys_then_default_value, - std::index_sequence) const; + auto + get(std::tuple keys_then_default_value, + std::index_sequence) const; template auto get_helper(const value_t& default_value, const string_t& key, rest_keys_t&&... rest) const; template @@ -155,8 +179,10 @@ class basic_object template inline basic_object::basic_object(std::initializer_list init_list) - : _object_data(std::make_move_iterator(init_list.begin()), std::make_move_iterator(init_list.end())) -{} + : _object_data( + std::make_move_iterator(init_list.begin()), std::make_move_iterator(init_list.end())) +{ +} // template // inline basic_object::basic_object(const basic_value& val) : @@ -202,8 +228,9 @@ template template inline decltype(auto) basic_object::emplace(args_t&&... args) { - static_assert(std::is_constructible_v, - "Parameter can't be used to construct a raw_object::value_type"); + static_assert( + std::is_constructible_v, + "Parameter can't be used to construct a raw_object::value_type"); return _object_data.emplace(std::forward(args)...); } @@ -220,7 +247,8 @@ inline string_t basic_object::to_string() const string_t str { '{' }; for (auto iter = _object_data.cbegin(); iter != _object_data.cend();) { const auto& [key, val] = *iter; - str += char_t('"') + _utils::unescape_string(key) + string_t { '\"', ':' } + val.to_string(); + str += + char_t('"') + _utils::unescape_string(key) + string_t { '\"', ':' } + val.to_string(); if (++iter != _object_data.cend()) { str += ','; } @@ -238,8 +266,8 @@ inline string_t basic_object::format(size_t indent, size_t indent_time string_t str { '{', '\n' }; for (auto iter = _object_data.cbegin(); iter != _object_data.cend();) { const auto& [key, val] = *iter; - str += body_indent + char_t('"') + _utils::unescape_string(key) + string_t { '\"', ':', ' ' } + - val.format(indent, indent_times + 1); + str += body_indent + char_t('"') + _utils::unescape_string(key) + + string_t { '\"', ':', ' ' } + val.format(indent, indent_times + 1); if (++iter != _object_data.cend()) { str += ','; } @@ -276,28 +304,31 @@ template template inline auto basic_object::get(key_then_default_value_t&&... keys_then_default_value) const { - return get(std::forward_as_tuple(keys_then_default_value...), - std::make_index_sequence {}); + return get( + std::forward_as_tuple(keys_then_default_value...), + std::make_index_sequence {}); } template template -inline auto basic_object::get(std::tuple keys_then_default_value, - std::index_sequence) const +inline auto basic_object::get( + std::tuple keys_then_default_value, + std::index_sequence) const { constexpr unsigned long default_value_index = sizeof...(key_then_default_value_t) - 1; - return get_helper(std::get(keys_then_default_value), - std::get(keys_then_default_value)...); + return get_helper( + std::get(keys_then_default_value), + std::get(keys_then_default_value)...); } template template -inline auto basic_object::get_helper(const value_t& default_value, const string_t& key, - rest_keys_t&&... rest) const +inline auto basic_object::get_helper( + const value_t& default_value, const string_t& key, rest_keys_t&&... rest) const { - constexpr bool is_json = std::is_same_v, value_t> || - std::is_same_v, value_t> || - std::is_same_v, value_t>; + constexpr bool is_json = std::is_same_v, value_t> + || std::is_same_v, value_t> + || std::is_same_v, value_t>; constexpr bool is_string = std::is_constructible_v && !is_json; if (!contains(key)) { @@ -314,11 +345,12 @@ inline auto basic_object::get_helper(const value_t& default_value, con template template -inline auto basic_object::get_helper(const value_t& default_value, const string_t& key) const +inline auto + basic_object::get_helper(const value_t& default_value, const string_t& key) const { - constexpr bool is_json = std::is_same_v, value_t> || - std::is_same_v, value_t> || - std::is_same_v, value_t>; + constexpr bool is_json = std::is_same_v, value_t> + || std::is_same_v, value_t> + || std::is_same_v, value_t>; constexpr bool is_string = std::is_constructible_v && !is_json; if (!contains(key)) { @@ -358,7 +390,8 @@ inline std::optional basic_object::find(const string_t& key) return std::nullopt; } const auto& val = iter->second; - return val.template is() ? std::optional(val.template as()) : std::nullopt; + return val.template is() ? std::optional(val.template as()) + : std::nullopt; } template @@ -374,7 +407,8 @@ inline typename basic_object::iterator basic_object::end() n } template -inline typename basic_object::const_iterator basic_object::begin() const noexcept +inline typename basic_object::const_iterator + basic_object::begin() const noexcept { return _object_data.begin(); } @@ -386,7 +420,8 @@ inline typename basic_object::const_iterator basic_object::e } template -inline typename basic_object::const_iterator basic_object::cbegin() const noexcept +inline typename basic_object::const_iterator + basic_object::cbegin() const noexcept { return _object_data.cbegin(); } @@ -410,7 +445,8 @@ inline basic_value& basic_object::operator[](string_t&& key) } template -inline basic_object basic_object::operator|(const basic_object& rhs) const& +inline basic_object + basic_object::operator|(const basic_object& rhs) const& { basic_object temp = *this; temp._object_data.insert(rhs.begin(), rhs.end()); @@ -422,12 +458,14 @@ inline basic_object basic_object::operator|(basic_object temp = *this; // temp._object_data.merge(std::move(rhs._object_data)); - temp._object_data.insert(std::make_move_iterator(rhs.begin()), std::make_move_iterator(rhs.end())); + temp._object_data.insert( + std::make_move_iterator(rhs.begin()), std::make_move_iterator(rhs.end())); return temp; } template -inline basic_object basic_object::operator|(const basic_object& rhs) && +inline basic_object + basic_object::operator|(const basic_object& rhs) && { _object_data.insert(rhs.begin(), rhs.end()); return std::move(*this); @@ -461,11 +499,14 @@ inline bool basic_object::operator==(const basic_object& rhs return _object_data == rhs._object_data; } -template >, - typename enable_t = - std::enable_if_t || std::is_base_of_v>> +template < + typename ostream_t, + typename string_t, + typename std_ostream_t = std::basic_ostream< + typename string_t::value_type, + std::char_traits>, + typename enable_t = std::enable_if_t< + std::is_same_v || std::is_base_of_v>> ostream_t& operator<<(ostream_t& out, const basic_object& obj) { out << obj.format(); diff --git a/include/common/serialization.hpp b/include/common/serialization.hpp index cd02d62..8f799a6 100644 --- a/include/common/serialization.hpp +++ b/include/common/serialization.hpp @@ -9,82 +9,88 @@ namespace json { namespace _serialization_helper { - template - class is_serializable - { - template - static auto test(int) -> decltype(std::declval()(std::declval()), std::true_type()); - - template - static std::false_type test(...); - - public: - static constexpr bool value = decltype(test(0))::value; - }; - - struct empty_serializer - { - // sample: - // json::value operator()(const type_1&) const { return ...; } - // json::value operator()(const type_2&) const { return ...; } - // json::value operator()(const type_3&) const { return ...; } - }; - - template - void unable_to_serialize() - { - static_assert(!sizeof(T), "Unable to serialize T. " +template +class is_serializable +{ + template + static auto test(int) + -> decltype(std::declval()(std::declval()), std::true_type()); + + template + static std::false_type test(...); + +public: + static constexpr bool value = decltype(test(0))::value; +}; + +struct empty_serializer +{ + // sample: + // json::value operator()(const type_1&) const { return ...; } + // json::value operator()(const type_2&) const { return ...; } + // json::value operator()(const type_3&) const { return ...; } +}; + +template +void unable_to_serialize() +{ + static_assert( + !sizeof(T), + "Unable to serialize T. " #ifdef _MSC_VER - "See T below: " __FUNCSIG__ + "See T below: " __FUNCSIG__ #else - // "See T below: " __PRETTY_FUNCTION__ + // "See T below: " __PRETTY_FUNCTION__ #endif - ); - } + ); +} } namespace _serialization_helper { - template - class is_deserializable - { - template - static auto test(int) - -> decltype(std::declval()(std::declval>(), std::declval()), - std::true_type()); - - template - static std::false_type test(...); - - public: - static constexpr bool value = decltype(test(0))::value; - }; - - struct empty_deserializer - { - // sample: - // bool operator()(const json::value&, type_1&) const { return ...; } - // bool operator()(const json::value&, type_2&) const { return ...; } - // bool operator()(const json::value&, type_3&) const { return ...; } - }; - - template - void unable_to_deserialize() - { - static_assert(!sizeof(T), "Unable to deserialize T. " +template +class is_deserializable +{ + template + static auto test(int) + -> decltype(std::declval()(std::declval>(), std::declval()), std::true_type()); + + template + static std::false_type test(...); + +public: + static constexpr bool value = decltype(test(0))::value; +}; + +struct empty_deserializer +{ + // sample: + // bool operator()(const json::value&, type_1&) const { return ...; } + // bool operator()(const json::value&, type_2&) const { return ...; } + // bool operator()(const json::value&, type_3&) const { return ...; } +}; + +template +void unable_to_deserialize() +{ + static_assert( + !sizeof(T), + "Unable to deserialize T. " #ifdef _MSC_VER - "See T below: " __FUNCSIG__ + "See T below: " __FUNCSIG__ #else - // "See T below: " __PRETTY_FUNCTION__ + // "See T below: " __PRETTY_FUNCTION__ #endif - ); - } + ); +} } -template +template < + typename in_t, + typename serializer_t = _serialization_helper::empty_serializer, + typename string_t = default_string_t> basic_value serialize(in_t&& in, const serializer_t& serializer = {}) { if constexpr (_serialization_helper::is_serializable::value) { @@ -98,7 +104,8 @@ basic_value serialize(in_t&& in, const serializer_t& serializer = {}) for (auto&& elem : in) { using elem_t = decltype(elem); - auto j_elem = serialize(std::forward(elem), serializer); + auto j_elem = + serialize(std::forward(elem), serializer); arr.emplace_back(std::move(j_elem)); } return arr; @@ -109,7 +116,8 @@ basic_value serialize(in_t&& in, const serializer_t& serializer = {}) using key_t = decltype(key); using elem_t = decltype(elem); - auto j_elem = serialize(std::forward(elem), serializer); + auto j_elem = + serialize(std::forward(elem), serializer); obj.emplace(std::forward(key), std::move(j_elem)); } return obj; @@ -119,9 +127,12 @@ basic_value serialize(in_t&& in, const serializer_t& serializer = {}) } } -template -bool deserialize(const basic_value& in, out_t& out, const deserializer_t& deserializer = {}) +template < + typename out_t, + typename deserializer_t = _serialization_helper::empty_deserializer, + typename string_t = default_string_t> +bool deserialize( + const basic_value& in, out_t& out, const deserializer_t& deserializer = {}) { if constexpr (_serialization_helper::is_deserializable::value) { return deserializer(in, out); diff --git a/include/common/types.hpp b/include/common/types.hpp index 2f56328..35370a6 100644 --- a/include/common/types.hpp +++ b/include/common/types.hpp @@ -2,4 +2,4 @@ #include "array.hpp" #include "object.hpp" -#include "value.hpp" \ No newline at end of file +#include "value.hpp" diff --git a/include/common/utils.hpp b/include/common/utils.hpp index f4779af..9939b50 100644 --- a/include/common/utils.hpp +++ b/include/common/utils.hpp @@ -61,7 +61,8 @@ constexpr bool is_container constexpr bool is_map = false; template -constexpr bool is_map> = is_container; +constexpr bool is_map> = + is_container; template constexpr bool is_collection = false; @@ -85,7 +86,8 @@ template class has_to_json_in_templ_spec { template - static auto test(int) -> decltype(std::declval>().to_json(std::declval()), std::true_type()); + static auto test(int) + -> decltype(std::declval>().to_json(std::declval()), std::true_type()); template static std::false_type test(...); @@ -113,8 +115,7 @@ class has_check_json_in_templ_spec { template static auto test(int) - -> decltype(std::declval>().check_json(std::declval>()), - std::true_type()); + -> decltype(std::declval>().check_json(std::declval>()), std::true_type()); template static std::false_type test(...); @@ -142,9 +143,7 @@ class has_from_json_in_templ_spec { template static auto test(int) - -> decltype(std::declval>().from_json(std::declval>(), - std::declval()), - std::true_type()); + -> decltype(std::declval>().from_json(std::declval>(), std::declval()), std::true_type()); template static std::false_type test(...); diff --git a/include/common/value.hpp b/include/common/value.hpp index bdc01af..199e5fa 100644 --- a/include/common/value.hpp +++ b/include/common/value.hpp @@ -64,30 +64,49 @@ class basic_value template basic_value(value_type type, args_t&&... args); - template && - std::is_constructible_v::value_type, - _utils::range_value_t>, - bool> = true> - basic_value(collection_t&& collection) : basic_value(basic_array(std::forward(collection))) - {} - template && - std::is_constructible_v::value_type, - _utils::range_value_t>, - bool> = true> - basic_value(map_t&& map) : basic_value(basic_object(std::forward(map))) - {} - - template ::value, bool> = true> - basic_value(const jsonization_t& value) : basic_value(value.to_json()) - {} - template ::value, bool> = true> - basic_value(const jsonization_t& value) : basic_value(ext::jsonization().to_json(value)) - {} - - template >, bool> = true> + template < + typename collection_t, + std::enable_if_t< + _utils::is_collection + && std::is_constructible_v< + typename basic_array::value_type, + _utils::range_value_t>, + bool> = true> + basic_value(collection_t&& collection) + : basic_value(basic_array(std::forward(collection))) + { + } + template < + typename map_t, + std::enable_if_t< + _utils::is_map + && std::is_constructible_v< + typename basic_object::value_type, + _utils::range_value_t>, + bool> = true> + basic_value(map_t&& map) + : basic_value(basic_object(std::forward(map))) + { + } + + template < + typename jsonization_t, + std::enable_if_t<_utils::has_to_json_in_member::value, bool> = true> + basic_value(const jsonization_t& value) + : basic_value(value.to_json()) + { + } + template < + typename jsonization_t, + std::enable_if_t<_utils::has_to_json_in_templ_spec::value, bool> = true> + basic_value(const jsonization_t& value) + : basic_value(ext::jsonization().to_json(value)) + { + } + + template < + typename value_t, + std::enable_if_t>, bool> = true> basic_value(value_t) = delete; // I don't know if you want to convert char to string or number, so I delete these constructors. @@ -162,14 +181,19 @@ class basic_value void clear() noexcept; - string_t dumps(std::optional indent = std::nullopt) const { return indent ? format(*indent) : to_string(); } + string_t dumps(std::optional indent = std::nullopt) const + { + return indent ? format(*indent) : to_string(); + } // return raw string string_t to_string() const; string_t format(size_t indent = 4) const { return format(indent, 0); } basic_value& operator=(const basic_value& rhs); basic_value& operator=(basic_value&&) noexcept; - template >, bool> = true> + template < + typename value_t, + std::enable_if_t>, bool> = true> basic_value& operator=(value_t rhs) { return *this = basic_value(std::move(rhs)); @@ -214,20 +238,26 @@ class basic_value explicit operator basic_array() const { return as_array(); } explicit operator basic_object() const { return as_object(); } - template typename collection_t = std::vector, - std::enable_if_t<_utils::is_collection>, bool> = true> + template < + typename value_t, + template typename collection_t = std::vector, + std::enable_if_t<_utils::is_collection>, bool> = true> explicit operator collection_t() const { return as_collection(); } - template typename map_t = std::map, - std::enable_if_t<_utils::is_map>, bool> = true> + template < + typename value_t, + template typename map_t = std::map, + std::enable_if_t<_utils::is_map>, bool> = true> explicit operator map_t() const { return as_map(); } - template ::value, bool> = true> + template < + typename jsonization_t, + std::enable_if_t<_utils::has_from_json_in_member::value, bool> = + true> explicit operator jsonization_t() const { jsonization_t dst {}; @@ -236,8 +266,11 @@ class basic_value } return dst; } - template ::value, bool> = true> + template < + typename jsonization_t, + std::enable_if_t< + _utils::has_from_json_in_templ_spec::value, + bool> = true> explicit operator jsonization_t() const { jsonization_t dst {}; @@ -256,8 +289,9 @@ class basic_value static var_t deep_copy(const var_t& src); template - auto get(std::tuple keys_then_default_value, - std::index_sequence) const; + auto + get(std::tuple keys_then_default_value, + std::index_sequence) const; template auto get_helper(const value_t& default_value, first_key_t&& first, rest_keys_t&&... rest) const; @@ -276,89 +310,125 @@ inline basic_value::basic_value() = default; template inline basic_value::basic_value(const basic_value& rhs) - : _type(rhs._type), _raw_data(deep_copy(rhs._raw_data)) -{} + : _type(rhs._type) + , _raw_data(deep_copy(rhs._raw_data)) +{ +} template inline basic_value::basic_value(basic_value&& rhs) noexcept = default; template inline basic_value::basic_value(bool b) - : _type(value_type::boolean), - _raw_data(string_t(b ? _utils::true_string() : _utils::false_string())) -{} + : _type(value_type::boolean) + , _raw_data(string_t(b ? _utils::true_string() : _utils::false_string())) +{ +} template inline basic_value::basic_value(int num) - : _type(value_type::number), _raw_data(_utils::to_basic_string(num)) -{} + : _type(value_type::number) + , _raw_data(_utils::to_basic_string(num)) +{ +} template inline basic_value::basic_value(unsigned num) - : _type(value_type::number), _raw_data(_utils::to_basic_string(num)) -{} + : _type(value_type::number) + , _raw_data(_utils::to_basic_string(num)) +{ +} template inline basic_value::basic_value(long num) - : _type(value_type::number), _raw_data(_utils::to_basic_string(num)) -{} + : _type(value_type::number) + , _raw_data(_utils::to_basic_string(num)) +{ +} template inline basic_value::basic_value(unsigned long num) - : _type(value_type::number), _raw_data(_utils::to_basic_string(num)) -{} + : _type(value_type::number) + , _raw_data(_utils::to_basic_string(num)) +{ +} template inline basic_value::basic_value(long long num) - : _type(value_type::number), _raw_data(_utils::to_basic_string(num)) -{} + : _type(value_type::number) + , _raw_data(_utils::to_basic_string(num)) +{ +} template inline basic_value::basic_value(unsigned long long num) - : _type(value_type::number), _raw_data(_utils::to_basic_string(num)) -{} + : _type(value_type::number) + , _raw_data(_utils::to_basic_string(num)) +{ +} template inline basic_value::basic_value(float num) - : _type(value_type::number), _raw_data(_utils::to_basic_string(num)) -{} + : _type(value_type::number) + , _raw_data(_utils::to_basic_string(num)) +{ +} template inline basic_value::basic_value(double num) - : _type(value_type::number), _raw_data(_utils::to_basic_string(num)) -{} + : _type(value_type::number) + , _raw_data(_utils::to_basic_string(num)) +{ +} template inline basic_value::basic_value(long double num) - : _type(value_type::number), _raw_data(_utils::to_basic_string(num)) -{} + : _type(value_type::number) + , _raw_data(_utils::to_basic_string(num)) +{ +} template -inline basic_value::basic_value(const char_t* str) : _type(value_type::string), _raw_data(string_t(str)) -{} +inline basic_value::basic_value(const char_t* str) + : _type(value_type::string) + , _raw_data(string_t(str)) +{ +} template -inline basic_value::basic_value(string_t str) : _type(value_type::string), _raw_data(std::move(str)) -{} +inline basic_value::basic_value(string_t str) + : _type(value_type::string) + , _raw_data(std::move(str)) +{ +} template -inline basic_value::basic_value(std::nullptr_t) : _type(value_type::null) -{} +inline basic_value::basic_value(std::nullptr_t) + : _type(value_type::null) +{ +} template inline basic_value::basic_value(basic_array arr) - : _type(value_type::array), _raw_data(std::make_unique>(std::move(arr))) -{} + : _type(value_type::array) + , _raw_data(std::make_unique>(std::move(arr))) +{ +} template inline basic_value::basic_value(basic_object obj) - : _type(value_type::object), _raw_data(std::make_unique>(std::move(obj))) -{} + : _type(value_type::object) + , _raw_data(std::make_unique>(std::move(obj))) +{ +} template -inline basic_value::basic_value(std::initializer_list::value_type> init_list) - : _type(value_type::object), _raw_data(std::make_unique>(init_list)) -{} +inline basic_value::basic_value( + std::initializer_list::value_type> init_list) + : _type(value_type::object) + , _raw_data(std::make_unique>(init_list)) +{ +} // for Pimpl template @@ -396,8 +466,8 @@ inline bool basic_value::is() const noexcept return is_object(); } else if constexpr (_utils::is_map) { - return is_object() && std::is_constructible_v && - all(); + return is_object() && std::is_constructible_v + && all(); } else { static_assert(!sizeof(value_t), "Unsupported type"); @@ -444,33 +514,40 @@ template template inline auto basic_value::get(key_then_default_value_t&&... keys_then_default_value) const { - return get(std::forward_as_tuple(keys_then_default_value...), - std::make_index_sequence {}); + return get( + std::forward_as_tuple(keys_then_default_value...), + std::make_index_sequence {}); } template template -inline auto basic_value::get(std::tuple keys_then_default_value, - std::index_sequence) const +inline auto basic_value::get( + std::tuple keys_then_default_value, + std::index_sequence) const { constexpr unsigned long default_value_index = sizeof...(key_then_default_value_t) - 1; - return get_helper(std::get(keys_then_default_value), - std::get(keys_then_default_value)...); + return get_helper( + std::get(keys_then_default_value), + std::get(keys_then_default_value)...); } template template -inline auto basic_value::get_helper(const value_t& default_value, first_key_t&& first, - rest_keys_t&&... rest) const +inline auto basic_value::get_helper( + const value_t& default_value, first_key_t&& first, rest_keys_t&&... rest) const { if constexpr (std::is_constructible_v) { - return is_object() ? as_object().get_helper(default_value, std::forward(first), - std::forward(rest)...) + return is_object() ? as_object().get_helper( + default_value, + std::forward(first), + std::forward(rest)...) : default_value; } else if constexpr (std::is_integral_v>) { - return is_array() ? as_array().get_helper(default_value, std::forward(first), - std::forward(rest)...) + return is_array() ? as_array().get_helper( + default_value, + std::forward(first), + std::forward(rest)...) : default_value; } else { @@ -480,16 +557,21 @@ inline auto basic_value::get_helper(const value_t& default_value, firs template template -inline auto basic_value::get_helper(const value_t& default_value, unique_key_t&& first) const +inline auto + basic_value::get_helper(const value_t& default_value, unique_key_t&& first) const { if constexpr (std::is_constructible_v) { - return is_object() ? as_object().get_helper(default_value, std::forward(first)) : default_value; + return is_object() + ? as_object().get_helper(default_value, std::forward(first)) + : default_value; } else if constexpr (std::is_integral_v>) { - return is_array() ? as_array().get_helper(default_value, std::forward(first)) : default_value; + return is_array() ? as_array().get_helper(default_value, std::forward(first)) + : default_value; } else { - static_assert(!sizeof(unique_key_t), "Parameter must be integral or string_t constructible"); + static_assert( + !sizeof(unique_key_t), "Parameter must be integral or string_t constructible"); } } @@ -722,10 +804,13 @@ template template inline decltype(auto) basic_value::emplace(args_t&&... args) { - constexpr bool is_array_args = std::is_constructible_v::value_type, args_t...>; - constexpr bool is_object_args = std::is_constructible_v::value_type, args_t...>; + constexpr bool is_array_args = + std::is_constructible_v::value_type, args_t...>; + constexpr bool is_object_args = + std::is_constructible_v::value_type, args_t...>; - static_assert(is_array_args || is_object_args, "Args can not constructure a array or object value"); + static_assert( + is_array_args || is_object_args, "Args can not constructure a array or object value"); if constexpr (is_array_args) { return as_array().emplace_back(std::forward(args)...); @@ -818,12 +903,15 @@ inline basic_value& basic_value::operator=(const basic_value } template -inline basic_value& basic_value::operator=(basic_value&& rhs) noexcept = default; +inline basic_value& + basic_value::operator=(basic_value&& rhs) noexcept = default; template inline bool basic_value::operator==(const basic_value& rhs) const { - if (_type != rhs._type) return false; + if (_type != rhs._type) { + return false; + } switch (_type) { case value_type::null: @@ -878,7 +966,8 @@ inline basic_value& basic_value::operator[](string_t&& key) } template -inline basic_value basic_value::operator|(const basic_object& rhs) const& +inline basic_value + basic_value::operator|(const basic_object& rhs) const& { return as_object() | rhs; } @@ -916,7 +1005,8 @@ inline basic_value& basic_value::operator|=(basic_object -inline basic_value basic_value::operator+(const basic_array& rhs) const& +inline basic_value + basic_value::operator+(const basic_array& rhs) const& { return as_array() + rhs; } @@ -956,9 +1046,11 @@ inline basic_value& basic_value::operator+=(basic_array template inline basic_value::basic_value(value_type type, args_t&&... args) - : _type(type), _raw_data(std::forward(args)...) + : _type(type) + , _raw_data(std::forward(args)...) { - static_assert(std::is_constructible_v, "Parameter can't be used to construct a var_t"); + static_assert( + std::is_constructible_v, "Parameter can't be used to construct a var_t"); } template @@ -981,11 +1073,14 @@ inline typename basic_value::var_t basic_value::deep_copy(co return dst; } -template >, - typename = - std::enable_if_t || std::is_base_of_v>> +template < + typename ostream_t, + typename string_t, + typename std_ostream_t = std::basic_ostream< + typename string_t::value_type, + std::char_traits>, + typename = std::enable_if_t< + std::is_same_v || std::is_base_of_v>> ostream_t& operator<<(ostream_t& out, const basic_value& val) { out << val.format(); diff --git a/include/json5.hpp b/include/json5.hpp index 1101c66..e6d3919 100644 --- a/include/json5.hpp +++ b/include/json5.hpp @@ -1,4 +1,4 @@ #pragma once #include "common/types.hpp" -#include "parser5/parser5.hpp" \ No newline at end of file +#include "parser5/parser5.hpp" diff --git a/include/parser/bitops.hpp b/include/parser/bitops.hpp index e1db493..f30eea3 100644 --- a/include/parser/bitops.hpp +++ b/include/parser/bitops.hpp @@ -20,14 +20,22 @@ namespace json::_bitops #if defined(__GNUC__) || defined(__clang__) inline constexpr int countl_zero(uint32_t x) { - if constexpr (sizeof(uint32_t) == sizeof(unsigned int)) return x == 0 ? 32 : __builtin_clz(x); - if constexpr (sizeof(uint32_t) == sizeof(unsigned long)) return x == 0 ? 32 : __builtin_clzl(x); + if constexpr (sizeof(uint32_t) == sizeof(unsigned int)) { + return x == 0 ? 32 : __builtin_clz(x); + } + if constexpr (sizeof(uint32_t) == sizeof(unsigned long)) { + return x == 0 ? 32 : __builtin_clzl(x); + } return x == 0 ? 32 : __builtin_clzll(x); } inline constexpr int countr_zero(uint32_t x) { - if constexpr (sizeof(uint32_t) == sizeof(unsigned int)) return x == 0 ? 32 : __builtin_ctz(x); - if constexpr (sizeof(uint32_t) == sizeof(unsigned long)) return x == 0 ? 32 : __builtin_ctzl(x); + if constexpr (sizeof(uint32_t) == sizeof(unsigned int)) { + return x == 0 ? 32 : __builtin_ctz(x); + } + if constexpr (sizeof(uint32_t) == sizeof(unsigned long)) { + return x == 0 ? 32 : __builtin_ctzl(x); + } return x == 0 ? 32 : __builtin_ctzll(x); } inline constexpr int countl_zero(uint64_t x) @@ -102,7 +110,8 @@ inline int countr_one(uint64_t x) // no constexpr endian awareness before C++20 inline bool is_little_endian() { - union { + union + { uint32_t u32; uint8_t u8; } u = { 0x01020304 }; diff --git a/include/parser/packed_bytes_arm.hpp b/include/parser/packed_bytes_arm.hpp index 05e59f3..0516c09 100644 --- a/include/parser/packed_bytes_arm.hpp +++ b/include/parser/packed_bytes_arm.hpp @@ -17,7 +17,10 @@ struct packed_bytes_trait_neon static constexpr auto step = 16; using value_type = uint8x16_t; - __packed_bytes_strong_inline static value_type load_unaligned(const void* ptr) { return vld1q_u8((uint8_t*)ptr); } + __packed_bytes_strong_inline static value_type load_unaligned(const void* ptr) + { + return vld1q_u8((uint8_t*)ptr); + } __packed_bytes_strong_inline static value_type less(value_type x, uint8_t n) { @@ -26,19 +29,30 @@ struct packed_bytes_trait_neon return is_less; } - __packed_bytes_strong_inline static value_type equal(value_type x, uint8_t n) { return vceqq_u8(x, vdupq_n_u8(n)); } + __packed_bytes_strong_inline static value_type equal(value_type x, uint8_t n) + { + return vceqq_u8(x, vdupq_n_u8(n)); + } - __packed_bytes_strong_inline static value_type equal(value_type x, value_type y) { return vceqq_u8(x, y); } + __packed_bytes_strong_inline static value_type equal(value_type x, value_type y) + { + return vceqq_u8(x, y); + } - __packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b) { return vorrq_u8(a, b); } + __packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b) + { + return vorrq_u8(a, b); + } __packed_bytes_strong_inline static bool is_all_zero(value_type x) { #ifdef __packed_bytes_trait_arm64 return vmaxvq_u8(x) == 0; #else - auto fold64 = vorr_u64(vget_high_u64(vreinterpretq_u8_u64(x), 0), vget_low_u64(vreinterpretq_u8_u64(x), 1)); - auto fold32 = vget_lane_u32(vreinterpret_u64_u32(fold64), 0) | vget_lane_u32(vreinterpret_u64_u32(fold64), 1); + auto fold64 = vorr_u64( + vget_high_u64(vreinterpretq_u8_u64(x), 0), vget_low_u64(vreinterpretq_u8_u64(x), 1)); + auto fold32 = vget_lane_u32(vreinterpret_u64_u32(fold64), 0) + | vget_lane_u32(vreinterpret_u64_u32(fold64), 1); return fold32 == 0; #endif } diff --git a/include/parser/packed_bytes_x86.hpp b/include/parser/packed_bytes_x86.hpp index ff1eb46..e01e502 100644 --- a/include/parser/packed_bytes_x86.hpp +++ b/include/parser/packed_bytes_x86.hpp @@ -35,9 +35,15 @@ struct packed_bytes_trait_sse return _mm_cmpeq_epi8(x, _mm_set1_epi8(static_cast(n))); } - __packed_bytes_strong_inline static value_type equal(value_type x, value_type y) { return _mm_cmpeq_epi8(x, y); } + __packed_bytes_strong_inline static value_type equal(value_type x, value_type y) + { + return _mm_cmpeq_epi8(x, y); + } - __packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b) { return _mm_or_si128(a, b); } + __packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b) + { + return _mm_or_si128(a, b); + } __packed_bytes_strong_inline static bool is_all_zero(value_type x) { @@ -97,14 +103,20 @@ struct packed_bytes_trait_avx2 return _mm256_cmpeq_epi8(x, _mm256_set1_epi8(static_cast(n))); } - __packed_bytes_strong_inline static value_type equal(value_type x, value_type y) { return _mm256_cmpeq_epi8(x, y); } + __packed_bytes_strong_inline static value_type equal(value_type x, value_type y) + { + return _mm256_cmpeq_epi8(x, y); + } __packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b) { return _mm256_or_si256(a, b); } - __packed_bytes_strong_inline static bool is_all_zero(value_type x) { return (bool)_mm256_testz_si256(x, x); } + __packed_bytes_strong_inline static bool is_all_zero(value_type x) + { + return (bool)_mm256_testz_si256(x, x); + } __packed_bytes_strong_inline static size_t first_nonzero_byte(value_type x) { diff --git a/include/parser/parser.hpp b/include/parser/parser.hpp index 6bf0652..8be9dce 100644 --- a/include/parser/parser.hpp +++ b/include/parser/parser.hpp @@ -15,8 +15,10 @@ namespace json // * parser declare * // **************************** -template +template < + typename string_t = default_string_t, + typename parsing_t = void, + typename accel_traits = _packed_bytes::packed_bytes_trait_max> class parser { public: @@ -28,7 +30,12 @@ class parser static std::optional> parse(const parsing_t& content); private: - parser(parsing_iter_t cbegin, parsing_iter_t cend) noexcept : _cur(cbegin), _end(cend) { ; } + parser(parsing_iter_t cbegin, parsing_iter_t cend) noexcept + : _cur(cbegin) + , _end(cend) + { + ; + } std::optional> parse(); basic_value parse_value(); @@ -63,8 +70,10 @@ auto parse(const parsing_t& content); template auto parse(char_t* content); -template , istream_t>>> +template < + typename istream_t, + typename = std::enable_if_t< + std::is_base_of_v, istream_t>>> auto parse(istream_t& istream, bool check_bom); template @@ -72,17 +81,17 @@ auto open(const path_t& path, bool check_bom = false); namespace literals { - value operator""_json(const char* str, size_t len); - wvalue operator""_json(const wchar_t* str, size_t len); +value operator""_json(const char* str, size_t len); +wvalue operator""_json(const wchar_t* str, size_t len); - value operator""_jvalue(const char* str, size_t len); - wvalue operator""_jvalue(const wchar_t* str, size_t len); +value operator""_jvalue(const char* str, size_t len); +wvalue operator""_jvalue(const wchar_t* str, size_t len); - array operator""_jarray(const char* str, size_t len); - warray operator""_jarray(const wchar_t* str, size_t len); +array operator""_jarray(const char* str, size_t len); +warray operator""_jarray(const wchar_t* str, size_t len); - object operator""_jobject(const char* str, size_t len); - wobject operator""_jobject(const wchar_t* str, size_t len); +object operator""_jobject(const char* str, size_t len); +wobject operator""_jobject(const wchar_t* str, size_t len); } template @@ -93,7 +102,8 @@ const basic_value invalid_value(); // ************************* template -inline std::optional> parser::parse(const parsing_t& content) +inline std::optional> + parser::parse(const parsing_t& content) { return parser(content.cbegin(), content.cend()).parse(); } @@ -252,7 +262,8 @@ inline basic_value parser::parse_st if (!string_opt) { return invalid_value(); } - return basic_value(basic_value::value_type::string, std::move(string_opt).value()); + return basic_value( + basic_value::value_type::string, std::move(string_opt).value()); } template @@ -456,8 +467,10 @@ inline bool parser::skip_string_literal_with_ while (_end - _cur >= accel_traits::step) { auto pack = accel_traits::load_unaligned(&(*_cur)); auto result = accel_traits::less(pack, 32); - result = accel_traits::bitwise_or(result, accel_traits::equal(pack, static_cast('"'))); - result = accel_traits::bitwise_or(result, accel_traits::equal(pack, static_cast('\\'))); + result = + accel_traits::bitwise_or(result, accel_traits::equal(pack, static_cast('"'))); + result = + accel_traits::bitwise_or(result, accel_traits::equal(pack, static_cast('\\'))); if (accel_traits::is_all_zero(result)) { _cur += accel_traits::step; @@ -551,8 +564,8 @@ auto parse(istream_t& ifs, bool check_bom) static constexpr uchar Bom_1 = 0xBB; static constexpr uchar Bom_2 = 0xBF; - if (str.size() >= 3 && static_cast(str.at(0)) == Bom_0 && static_cast(str.at(1)) == Bom_1 && - static_cast(str.at(2)) == Bom_2) { + if (str.size() >= 3 && static_cast(str.at(0)) == Bom_0 + && static_cast(str.at(1)) == Bom_1 && static_cast(str.at(2)) == Bom_2) { str.assign(str.begin() + 3, str.end()); } } @@ -578,50 +591,51 @@ auto open(const path_t& filepath, bool check_bom) namespace literals { - inline value operator""_json(const char* str, size_t len) - { - return operator""_jvalue(str, len); - } - inline wvalue operator""_json(const wchar_t* str, size_t len) - { - return operator""_jvalue(str, len); - } +inline value operator""_json(const char* str, size_t len) +{ + return operator""_jvalue(str, len); +} +inline wvalue operator""_json(const wchar_t* str, size_t len) +{ + return operator""_jvalue(str, len); +} - inline value operator""_jvalue(const char* str, size_t len) - { - return parse(std::string_view(str, len)).value_or(value()); - } - inline wvalue operator""_jvalue(const wchar_t* str, size_t len) - { - return parse(std::wstring_view(str, len)).value_or(wvalue()); - } +inline value operator""_jvalue(const char* str, size_t len) +{ + return parse(std::string_view(str, len)).value_or(value()); +} +inline wvalue operator""_jvalue(const wchar_t* str, size_t len) +{ + return parse(std::wstring_view(str, len)).value_or(wvalue()); +} - inline array operator""_jarray(const char* str, size_t len) - { - auto val = parse(std::string_view(str, len)).value_or(value()); - return val.is_array() ? val.as_array() : array(); - } - inline warray operator""_jarray(const wchar_t* str, size_t len) - { - auto val = parse(std::wstring_view(str, len)).value_or(wvalue()); - return val.is_array() ? val.as_array() : warray(); - } +inline array operator""_jarray(const char* str, size_t len) +{ + auto val = parse(std::string_view(str, len)).value_or(value()); + return val.is_array() ? val.as_array() : array(); +} +inline warray operator""_jarray(const wchar_t* str, size_t len) +{ + auto val = parse(std::wstring_view(str, len)).value_or(wvalue()); + return val.is_array() ? val.as_array() : warray(); +} - inline object operator""_jobject(const char* str, size_t len) - { - auto val = parse(std::string_view(str, len)).value_or(value()); - return val.is_object() ? val.as_object() : object(); - } - inline wobject operator""_jobject(const wchar_t* str, size_t len) - { - auto val = parse(std::wstring_view(str, len)).value_or(wvalue()); - return val.is_object() ? val.as_object() : wobject(); - } +inline object operator""_jobject(const char* str, size_t len) +{ + auto val = parse(std::string_view(str, len)).value_or(value()); + return val.is_object() ? val.as_object() : object(); +} +inline wobject operator""_jobject(const wchar_t* str, size_t len) +{ + auto val = parse(std::wstring_view(str, len)).value_or(wvalue()); + return val.is_object() ? val.as_object() : wobject(); +} } // namespace literals template const basic_value invalid_value() { - return basic_value(basic_value::value_type::invalid, typename basic_value::var_t()); + return basic_value( + basic_value::value_type::invalid, typename basic_value::var_t()); } } // namespace json diff --git a/include/parser5/parser5.hpp b/include/parser5/parser5.hpp index 55cc97b..16783dc 100644 --- a/include/parser5/parser5.hpp +++ b/include/parser5/parser5.hpp @@ -50,8 +50,10 @@ class parser5 { public: InvalidChar(u8char ch = 0, const std::string& detail = "") - : exception("Invalid Char", "Unexpected token \'" + StringFromCharCode(ch) + "\'", detail) - {} + : exception( + "Invalid Char", "Unexpected token \'" + StringFromCharCode(ch) + "\'", detail) + { + } }; class InvalidIdentifier : public exception @@ -59,14 +61,17 @@ class parser5 public: InvalidIdentifier(const std::string& msg = "", const std::string& detail = "") : exception("Invalid Identifier", msg, detail) - {} + { + } }; class InvalidEOF : public exception { public: - InvalidEOF(const std::string& msg = "", const std::string& detail = "") : exception("Invalid EOF", msg, detail) - {} + InvalidEOF(const std::string& msg = "", const std::string& detail = "") + : exception("Invalid EOF", msg, detail) + { + } }; public: @@ -175,7 +180,12 @@ class parser5 static std::optional parse(const string_t& content, std::string* error = nullptr); private: - parser5(string_iter_t cbegin, string_iter_t cend) noexcept : _cur(cbegin), _end(cend), _line_begin_cur(cbegin) {} + parser5(string_iter_t cbegin, string_iter_t cend) noexcept + : _cur(cbegin) + , _end(cend) + , _line_begin_cur(cbegin) + { + } std::optional parse(); private: @@ -272,15 +282,15 @@ inline bool parser5::unicode::isSpaceSeparator(u8char ch) template inline bool parser5::unicode::isIdStartChar(u8char ch) { - return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '$') || (ch == '_') || - findInRange(json::unicode::id_start, toUnicode(ch)); + return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '$') || (ch == '_') + || findInRange(json::unicode::id_start, toUnicode(ch)); } template inline bool parser5::unicode::isIdContinueChar(u8char ch) { - return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || (ch == '$') || - (ch == '_') || findInRange(json::unicode::id_continue, toUnicode(ch)); + return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') + || (ch == '$') || (ch == '_') || findInRange(json::unicode::id_continue, toUnicode(ch)); } template @@ -346,7 +356,8 @@ inline bool parser5::unicode::findInRange(const array_t& range, u8char return false; } // set 中保存的是类似于 { start1, end1, start2, end2, ... } 的形式, 区间可表示为[start, end) - // 判断lb是否位于start的位置, 如果是, 则表示codePoint在某个区间的内部, 如果不是, 则表示codePoint在两个区间中间 + // 判断lb是否位于start的位置, 如果是, 则表示codePoint在某个区间的内部, 如果不是, + // 则表示codePoint在两个区间中间 return std::distance(begin, lb) % 2 == 0; } @@ -519,11 +530,13 @@ inline typename parser5::u8char parser5::unicodeEscape() /* utf-8 reader */ template -inline typename parser5::u8char parser5::peek(const string_iter_t& begin, const string_iter_t& end, - size_t* plen) +inline typename parser5::u8char + parser5::peek(const string_iter_t& begin, const string_iter_t& end, size_t* plen) { if (begin == end) { - if (plen) *plen = 0; + if (plen) { + *plen = 0; + } return 0; } uint8_t head = *begin; @@ -581,11 +594,15 @@ inline typename parser5::u8char parser5::read() template inline std::string parser5::StringFromCharCode(typename parser5::u8char code) { - if (code == 0) return ""; + if (code == 0) { + return ""; + } std::string str; for (auto i = 0; i < 8; ++i) { auto ch = (0xff & code); - if (ch) str.insert(0, 1, static_cast(ch)); + if (ch) { + str.insert(0, 1, static_cast(ch)); + } code >>= 8; } return str; @@ -700,7 +717,8 @@ inline std::optional::Token> parser5::lex_m } template -inline std::optional::Token> parser5::lex_multiLineCommentAsterisk() +inline std::optional::Token> + parser5::lex_multiLineCommentAsterisk() { switch (_current_char) { case '*': @@ -808,7 +826,8 @@ inline std::optional::Token> parser5::lex_v } template -inline std::optional::Token> parser5::lex_identifierNameStartEscape() +inline std::optional::Token> + parser5::lex_identifierNameStartEscape() { if (_current_char != 'u') { throw InvalidChar(_current_char, exceptionDetailInfo()); @@ -855,7 +874,8 @@ inline std::optional::Token> parser5::lex_i } template -inline std::optional::Token> parser5::lex_identifierNameEscape() +inline std::optional::Token> + parser5::lex_identifierNameEscape() { if (_current_char != 'u') { throw InvalidChar(_current_char, exceptionDetailInfo()); @@ -1047,7 +1067,8 @@ inline std::optional::Token> parser5::lex_d } template -inline std::optional::Token> parser5::lex_decimalExponentInteger() +inline std::optional::Token> + parser5::lex_decimalExponentInteger() { if (unicode::isDigit(_current_char)) { _buffer += StringFromCharCode(read()); @@ -1386,7 +1407,8 @@ inline void parser5::parse_afterArrayValue() template inline void parser5::parse_end() -{} +{ +} template inline void parser5::parseStates(ParseState state) diff --git a/include/reflection/jsonization.hpp b/include/reflection/jsonization.hpp index e6507ed..7291648 100644 --- a/include/reflection/jsonization.hpp +++ b/include/reflection/jsonization.hpp @@ -8,9 +8,11 @@ namespace json::_jsonization_helper { struct next_is_optional_t -{}; +{ +}; struct va_arg_end -{}; +{ +}; struct dumper { @@ -32,8 +34,12 @@ struct dumper struct checker { template - bool _check_json(const json::value& in, std::string& error_key, const char* key, const var_t&, - rest_t&&... rest) const + bool _check_json( + const json::value& in, + std::string& error_key, + const char* key, + const var_t&, + rest_t&&... rest) const { auto opt = in.find(key); if (!opt || !opt->is()) { @@ -43,8 +49,14 @@ struct checker return _check_json(in, error_key, std::forward(rest)...); } template - bool _check_json(const json::value& in, std::string& error_key, const char*, next_is_optional_t, const char* key, - const var_t&, rest_t&&... rest) const + bool _check_json( + const json::value& in, + std::string& error_key, + const char*, + next_is_optional_t, + const char* key, + const var_t&, + rest_t&&... rest) const { auto opt = in.find(key); if (opt) { @@ -62,7 +74,12 @@ struct checker struct loader { template - bool _from_json(const json::value& in, std::string& error_key, const char* key, var_t& var, rest_t&&... rest) const + bool _from_json( + const json::value& in, + std::string& error_key, + const char* key, + var_t& var, + rest_t&&... rest) const { auto opt = in.find(key); if (!opt || !opt->is()) { @@ -74,8 +91,14 @@ struct loader return _from_json(in, error_key, std::forward(rest)...); } template - bool _from_json(const json::value& in, std::string& error_key, const char*, next_is_optional_t, const char* key, - var_t& var, rest_t&&... rest) const + bool _from_json( + const json::value& in, + std::string& error_key, + const char*, + next_is_optional_t, + const char* key, + var_t& var, + rest_t&&... rest) const { auto opt = in.find(key); if (opt) { @@ -111,122 +134,319 @@ namespace json::_private_macro #define _MEOJSON_FOR_EACH_0(pred, ...) #define _MEOJSON_FOR_EACH_1(pred, x, ...) pred(x) -#define _MEOJSON_FOR_EACH_2(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_1(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_3(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_2(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_4(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_3(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_5(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_4(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_6(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_5(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_7(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_6(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_8(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_7(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_9(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_8(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_10(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_9(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_11(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_10(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_12(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_11(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_13(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_12(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_14(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_13(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_15(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_14(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_16(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_15(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_17(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_16(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_18(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_17(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_19(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_18(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_20(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_19(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_21(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_20(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_22(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_21(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_23(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_22(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_24(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_23(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_25(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_24(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_26(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_25(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_27(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_26(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_28(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_27(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_29(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_28(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_30(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_29(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_31(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_30(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_32(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_31(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_33(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_32(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_34(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_33(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_35(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_34(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_36(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_35(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_37(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_36(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_38(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_37(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_39(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_38(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_40(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_39(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_41(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_40(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_42(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_41(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_43(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_42(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_44(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_43(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_45(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_44(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_46(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_45(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_47(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_46(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_48(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_47(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_49(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_48(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_50(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_49(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_51(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_50(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_52(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_51(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_53(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_52(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_54(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_53(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_55(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_54(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_56(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_55(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_57(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_56(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_58(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_57(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_59(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_58(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_60(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_59(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_61(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_60(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_62(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_61(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_63(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_62(pred, __VA_ARGS__)) -#define _MEOJSON_FOR_EACH_64(pred, x, ...) pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_63(pred, __VA_ARGS__)) - -#define _MEOJSON_ARG_COUNT(...) \ - _MEOJSON_EXPAND(_MEOJSON_ARG_COUNT1(0, ##__VA_ARGS__, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, \ - 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, \ - 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, \ - 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) -#define _MEOJSON_ARG_COUNT1(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, \ - _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, \ - _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, \ - _56, _57, _58, _59, _60, _61, _62, _63, _64, N, ...) \ +#define _MEOJSON_FOR_EACH_2(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_1(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_3(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_2(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_4(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_3(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_5(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_4(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_6(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_5(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_7(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_6(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_8(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_7(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_9(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_8(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_10(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_9(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_11(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_10(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_12(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_11(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_13(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_12(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_14(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_13(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_15(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_14(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_16(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_15(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_17(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_16(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_18(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_17(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_19(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_18(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_20(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_19(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_21(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_20(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_22(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_21(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_23(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_22(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_24(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_23(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_25(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_24(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_26(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_25(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_27(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_26(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_28(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_27(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_29(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_28(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_30(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_29(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_31(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_30(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_32(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_31(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_33(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_32(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_34(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_33(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_35(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_34(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_36(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_35(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_37(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_36(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_38(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_37(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_39(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_38(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_40(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_39(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_41(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_40(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_42(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_41(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_43(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_42(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_44(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_43(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_45(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_44(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_46(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_45(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_47(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_46(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_48(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_47(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_49(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_48(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_50(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_49(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_51(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_50(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_52(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_51(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_53(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_52(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_54(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_53(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_55(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_54(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_56(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_55(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_57(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_56(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_58(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_57(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_59(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_58(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_60(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_59(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_61(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_60(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_62(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_61(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_63(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_62(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_64(pred, x, ...) \ + pred(x) _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_63(pred, __VA_ARGS__)) + +#define _MEOJSON_ARG_COUNT(...) \ + _MEOJSON_EXPAND(_MEOJSON_ARG_COUNT1( \ + 0, \ + ##__VA_ARGS__, \ + 64, \ + 63, \ + 62, \ + 61, \ + 60, \ + 59, \ + 58, \ + 57, \ + 56, \ + 55, \ + 54, \ + 53, \ + 52, \ + 51, \ + 50, \ + 49, \ + 48, \ + 47, \ + 46, \ + 45, \ + 44, \ + 43, \ + 42, \ + 41, \ + 40, \ + 39, \ + 38, \ + 37, \ + 36, \ + 35, \ + 34, \ + 33, \ + 32, \ + 31, \ + 30, \ + 29, \ + 28, \ + 27, \ + 26, \ + 25, \ + 24, \ + 23, \ + 22, \ + 21, \ + 20, \ + 19, \ + 18, \ + 17, \ + 16, \ + 15, \ + 14, \ + 13, \ + 12, \ + 11, \ + 10, \ + 9, \ + 8, \ + 7, \ + 6, \ + 5, \ + 4, \ + 3, \ + 2, \ + 1, \ + 0)) +#define _MEOJSON_ARG_COUNT1( \ + _0, \ + _1, \ + _2, \ + _3, \ + _4, \ + _5, \ + _6, \ + _7, \ + _8, \ + _9, \ + _10, \ + _11, \ + _12, \ + _13, \ + _14, \ + _15, \ + _16, \ + _17, \ + _18, \ + _19, \ + _20, \ + _21, \ + _22, \ + _23, \ + _24, \ + _25, \ + _26, \ + _27, \ + _28, \ + _29, \ + _30, \ + _31, \ + _32, \ + _33, \ + _34, \ + _35, \ + _36, \ + _37, \ + _38, \ + _39, \ + _40, \ + _41, \ + _42, \ + _43, \ + _44, \ + _45, \ + _46, \ + _47, \ + _48, \ + _49, \ + _50, \ + _51, \ + _52, \ + _53, \ + _54, \ + _55, \ + _56, \ + _57, \ + _58, \ + _59, \ + _60, \ + _61, \ + _62, \ + _63, \ + _64, \ + N, \ + ...) \ N -#define _MEOJSON_FOR_EACH_(N, pred, ...) _MEOJSON_EXPAND(_MEOJSON_CONCATENATE(_MEOJSON_FOR_EACH_, N)(pred, __VA_ARGS__)) +#define _MEOJSON_FOR_EACH_(N, pred, ...) \ + _MEOJSON_EXPAND(_MEOJSON_CONCATENATE(_MEOJSON_FOR_EACH_, N)(pred, __VA_ARGS__)) #define _MEOJSON_FOR_EACH(pred, ...) \ - _MEOJSON_EXPAND(_MEOJSON_FOR_EACH_(_MEOJSON_EXPAND(_MEOJSON_ARG_COUNT(__VA_ARGS__)), pred, __VA_ARGS__)) + _MEOJSON_EXPAND( \ + _MEOJSON_FOR_EACH_(_MEOJSON_EXPAND(_MEOJSON_ARG_COUNT(__VA_ARGS__)), pred, __VA_ARGS__)) #define _MEOJSON_VARNAME(x) _MEOJSON_CONCATENATE(_meojson_jsonization_, x) #define _MEOJSON_KEY_VALUE(x) _MEOJSON_STRINGIZE(x), x, } // namespace json::_private_macro -#define MEO_TOJSON(...) \ - json::value to_json() const \ - { \ - return json::_jsonization_helper::dumper()._to_json(_MEOJSON_EXPAND( \ - _MEOJSON_FOR_EACH(_MEOJSON_KEY_VALUE, __VA_ARGS__)) json::_jsonization_helper::va_arg_end {}); \ +#define MEO_TOJSON(...) \ + json::value to_json() const \ + { \ + return json::_jsonization_helper::dumper()._to_json(_MEOJSON_EXPAND(_MEOJSON_FOR_EACH( \ + _MEOJSON_KEY_VALUE, __VA_ARGS__)) json::_jsonization_helper::va_arg_end {}); \ } -#define MEO_CHECKJSON(...) \ - bool check_json(const json::value& _MEOJSON_VARNAME(in)) const \ - { \ - std::string _MEOJSON_VARNAME(error_key); \ - return check_json(_MEOJSON_VARNAME(in), _MEOJSON_VARNAME(error_key)); \ - } \ - bool check_json(const json::value& _MEOJSON_VARNAME(in), std::string& _MEOJSON_VARNAME(error_key)) const \ - { \ - return json::_jsonization_helper::checker()._check_json( \ - _MEOJSON_VARNAME(in), _MEOJSON_VARNAME(error_key), \ - _MEOJSON_EXPAND(_MEOJSON_FOR_EACH(_MEOJSON_KEY_VALUE, __VA_ARGS__)) \ - json::_jsonization_helper::va_arg_end {}); \ +#define MEO_CHECKJSON(...) \ + bool check_json(const json::value& _MEOJSON_VARNAME(in)) const \ + { \ + std::string _MEOJSON_VARNAME(error_key); \ + return check_json(_MEOJSON_VARNAME(in), _MEOJSON_VARNAME(error_key)); \ + } \ + bool check_json( \ + const json::value& _MEOJSON_VARNAME(in), std::string& _MEOJSON_VARNAME(error_key)) const \ + { \ + return json::_jsonization_helper::checker()._check_json( \ + _MEOJSON_VARNAME(in), \ + _MEOJSON_VARNAME(error_key), \ + _MEOJSON_EXPAND(_MEOJSON_FOR_EACH(_MEOJSON_KEY_VALUE, __VA_ARGS__)) \ + json::_jsonization_helper::va_arg_end {}); \ } -#define MEO_FROMJSON(...) \ - bool from_json(const json::value& _MEOJSON_VARNAME(in)) \ - { \ - std::string _MEOJSON_VARNAME(error_key); \ - return from_json(_MEOJSON_VARNAME(in), _MEOJSON_VARNAME(error_key)); \ - } \ - bool from_json(const json::value& _MEOJSON_VARNAME(in), std::string& _MEOJSON_VARNAME(error_key)) \ - { \ - return json::_jsonization_helper::loader()._from_json( \ - _MEOJSON_VARNAME(in), _MEOJSON_VARNAME(error_key), \ - _MEOJSON_EXPAND(_MEOJSON_FOR_EACH(_MEOJSON_KEY_VALUE, __VA_ARGS__)) \ - json::_jsonization_helper::va_arg_end {}); \ +#define MEO_FROMJSON(...) \ + bool from_json(const json::value& _MEOJSON_VARNAME(in)) \ + { \ + std::string _MEOJSON_VARNAME(error_key); \ + return from_json(_MEOJSON_VARNAME(in), _MEOJSON_VARNAME(error_key)); \ + } \ + bool from_json( \ + const json::value& _MEOJSON_VARNAME(in), std::string& _MEOJSON_VARNAME(error_key)) \ + { \ + return json::_jsonization_helper::loader()._from_json( \ + _MEOJSON_VARNAME(in), \ + _MEOJSON_VARNAME(error_key), \ + _MEOJSON_EXPAND(_MEOJSON_FOR_EACH(_MEOJSON_KEY_VALUE, __VA_ARGS__)) \ + json::_jsonization_helper::va_arg_end {}); \ } #define MEO_JSONIZATION(...) \ diff --git a/sample/sample.cpp b/sample/sample.cpp index 810b930..90b6d1b 100644 --- a/sample/sample.cpp +++ b/sample/sample.cpp @@ -54,7 +54,9 @@ void serializing() std::set new_set = (std::set)j["set"]; // this crazy type again - auto new_map = (std::unordered_map>>>)j["map"]; + auto new_map = + (std::unordered_map>>>) + j["map"]; /* However, for runtime json, we'd better check whether it can be converted first. */ @@ -66,7 +68,8 @@ void serializing() std::cout << "Fortunately, I checked it, otherwise it will crash!" << std::endl; } - /* I guess you have understood, yes, **meojson** is not only a json library, but also a serialization library! */ + /* I guess you have understood, yes, **meojson** is not only a json library, but also a + * serialization library! */ struct MyStruct { @@ -81,12 +84,14 @@ void serializing() MyStruct mine; mine.vec.emplace_back(0.5); - mine.map = { { "key_1", { { { "inner_key_1", { 7, 8, 9 } } }, { { "inner_key_2", { 10 } } } } } }; + mine.map = { { "key_1", + { { { "inner_key_1", { 7, 8, 9 } } }, { { "inner_key_2", { 10 } } } } } }; // yes, it’s that intuitive and smooth! json::value j_mine = mine; - // output: {"map":{"key_1":[{"inner_key_1":[7,8,9]},{"inner_key_2":[10]}]},"vec":[0.500000],"x":0} + // output: + // {"map":{"key_1":[{"inner_key_1":[7,8,9]},{"inner_key_2":[10]}]},"vec":[0.500000],"x":0} std::cout << j_mine << std::endl; // exactly, we can also change it back! @@ -114,8 +119,8 @@ void serializing() // same deserialization Outter new_o = (Outter)j_outter; - /* For optional fields, we can add `MEO_OPT` to it, so that when converting, if this fields does not exist in json, - * it will be skipped. */ + /* For optional fields, we can add `MEO_OPT` to it, so that when converting, if this fields does + * not exist in json, it will be skipped. */ struct OptionalFields { @@ -185,7 +190,8 @@ class jsonization void third_party_jsonization_1() { - /* For third-party unhackable types, you need to implement `to_json`, `check_json`, `from_json` */ + /* For third-party unhackable types, you need to implement `to_json`, `check_json`, `from_json` + */ // then you can use it as json ThirdPartyStruct third; @@ -205,8 +211,8 @@ void third_party_jsonization_1() void third_party_jsonization_2() { - /* If you don't like stupid invasive function, you can use `json::serialize` and `json::deserialize` - * for more elegant conversion: */ + /* If you don't like stupid invasive function, you can use `json::serialize` and + * `json::deserialize` for more elegant conversion: */ struct Serializer { json::value operator()(const ThirdPartyStruct& t) const { return t.a; } @@ -215,7 +221,9 @@ void third_party_jsonization_2() { bool operator()(const json::value& j, ThirdPartyStruct& t) const { - if (!j.is_number()) return false; + if (!j.is_number()) { + return false; + } t.a = j.as_integer(); return true; } diff --git a/test/json5_test.cpp b/test/json5_test.cpp index d624632..6c2f754 100644 --- a/test/json5_test.cpp +++ b/test/json5_test.cpp @@ -52,7 +52,7 @@ bool parsing() std::cerr << "Parsing failed" << std::endl; std::cerr << error_message << std::endl; return false; - } // C-style strings can also be used as input. + } // C-style strings can also be used as input. } json::value& value = ret.value(); // you can use rvalues if needed, like // `auto value = std::move(ret).value();` diff --git a/test/serializing_test.cpp b/test/serializing_test.cpp index 57ab7da..0d9c53c 100644 --- a/test/serializing_test.cpp +++ b/test/serializing_test.cpp @@ -105,7 +105,8 @@ bool serializing() auto as_map_2 = root["obj from map"].as_map(); auto to_hashmap = root["obj from map"].as_map(); - std::vector>> complex { { { 1, 2, 3 }, { 4, 5 } }, { { 6 }, { 7, 8 } } }; + std::vector>> complex { { { 1, 2, 3 }, { 4, 5 } }, + { { 6 }, { 7, 8 } } }; root["complex"] = complex; root["a\\n"] = "1a\\n"; @@ -265,13 +266,14 @@ bool jsonizing() mine.str2 = "World"; mine.str3 = "!"; mine.vec.emplace_back(0.5); - mine.map = { { "key_1", { { { "inner_key_1", { 7, 8, 9 } } }, { { "inner_key_2", { 10 } } } } } }; + mine.map = { { "key_1", + { { { "inner_key_1", { 7, 8, 9 } } }, { { "inner_key_2", { 10 } } } } } }; json::value j_mine = mine; MyStruct new_mine = (MyStruct)j_mine; - bool ret = new_mine.str1 == "Hello" && new_mine.str2 == "World" && new_mine.str3 == "!" && new_mine.vec[0] == 0.5 && - new_mine.map["key_1"].size() == 2; + bool ret = new_mine.str1 == "Hello" && new_mine.str2 == "World" && new_mine.str3 == "!" + && new_mine.vec[0] == 0.5 && new_mine.map["key_1"].size() == 2; if (!ret) { std::cerr << "error new_mine" << std::endl; return false; @@ -285,7 +287,8 @@ bool jsonizing() return false; } - std::vector paths = { "/root/dir1/dir2/filename", "/root/dir1/dir2/filename2" }; + std::vector paths = { "/root/dir1/dir2/filename", + "/root/dir1/dir2/filename2" }; json::array jpaths = paths; std::vector new_paths = (std::vector)jpaths; if (new_paths != paths) { @@ -293,10 +296,12 @@ bool jsonizing() return false; } - std::map path_map = { { "key1", "/root/dir1/dir2/filename" }, - { "key2", "/root/dir1/dir2/filename2" } }; + std::map path_map = { + { "key1", "/root/dir1/dir2/filename" }, { "key2", "/root/dir1/dir2/filename2" } + }; json::object jpath_map = path_map; - std::map new_path_map = (std::map)jpath_map; + std::map new_path_map = + (std::map)jpath_map; if (new_path_map != path_map) { std::cerr << "error new_path_map" << std::endl; return false;