
تتميز مكتبة JSON Link بأداء عالٍ، ولا يوجد تخصيص، وتدعم مكتبة C++ JSON:
تدعم المكتبة أوضاع التحليل الأخرى التي يمكن مزجها أيضًا.
json_array_iterator أو json_array_range .json_value الذي يسمح بالتكرار/التحليل البطيء للمستندبعض الميزات البارزة الأخرى هي:
boost::multiprecision::cpp_int أو GNU BigNum/Rational mpq_tالمكتبة تستخدم ترخيص BSL
عندما تكون بنية مستند JSON معروفة، يكون التحليل كما يلي:
MyThing thing = daw::json::from_json<MyThing>( json_string );أو بالنسبة لمستندات المصفوفة، حيث يكون جذر المستند مصفوفة، هناك طريقة مساعدة لتسهيل الأمر، ويمكن تحليلها كما يلي:
std::vector<MyThing> things = daw::json::from_json_array<MyThing>( json_string2 ); إذا كانت بنية مستند JSON غير معروفة، فيمكن إنشاء قيمة json_value تعمل كعرض وتسمح بالتكرار والتحليل عند الطلب. فيما يلي مثال لفتح قيمة json_value من بيانات JSON:
json_value val = daw::json::json_value( json_string ); تسمح الطرق from_json و to_json بالوصول إلى معظم احتياجات التحليل والتسلسل.
يمكن استدعاء المحلل المعتمد على الحدث (SAX) عبر daw::json::json_event_parser . يستغرق الأمر وسيطتين، مستند json ومعالج الأحداث. يمكن لمعالج الأحداث الاشتراك في الأحداث من خلال وجود أي من الأعضاء التاليين:
يتم تعيين فئاتك إلى مستندات JSON عن طريق تخصيص السمة daw::json::json_data_contract . لا تحتاج الفئة التي تم تعيينها إلى تعيينها مرة أخرى إذا كانت عضوًا في فئة معينة أخرى. هناك جزأين للسمة json_data_contract ، الأول هو نوع الاسم المستعار المسمى type الذي يقوم بتعيين أعضاء JSON إلى مُنشئ الفصل الخاص بنا. يلتف هذا حول الحاجة إلى الوصول الخاص إلى الفصل، على افتراض أن البيانات التي سنقوم بتسلسلها ستكون ضرورية أيضًا لإنشاء الفصل. على سبيل المثال:
struct Thing {
int a;
int b;
}; تتطلب بنية Thing عددين صحيحين وإذا كان لدينا JSON التالي:
{
"a" : 42 ,
"b" : 1234
}يمكننا القيام بالرسم كما يلي:
namespace daw ::json {
template <>
struct json_data_contract <Thing> {
static constexpr char const a[] = " a " ;
static constexpr char const b[] = " b " ;
using type = json_member_list<
json_number<a, int >,
json_number<b, int >
>;
};
} يشير هذا إلى أن فئة JSON، في المستند، ستحتوي على عضوين على الأقل "a" و"b" وهما عبارة عن أرقام صحيحة. سيتم تمريرها إلى منشئ Thing عند daw::json::from_json<Thing>( json_doc ); يتم استدعاؤه، أو أن فئة أخرى لديها تعيين عضو json_class<MemberName, Thing> . ما ورد أعلاه هو طريقة تعيين الأسماء C++ 17، وهي تعمل في إصدارات C++ المستقبلية أيضًا. ولكن، في C++ 20 والإصدارات الأحدث، يمكن أن تكون الأسماء مضمنة في التعيين، على سبيل المثال json_number<"a", int> . ما ورد أعلاه هو كل ما هو مطلوب لتحليل JSON، لإجراء تسلسل لوظيفة عضو ثابت مطلوبة في السمة. بأخذ المثال السابق وتوسيعه يمكننا إجراء تسلسل لـ Thing باستخدام:
namespace daw ::json {
template <>
struct json_data_contract <Thing> {
static constexpr char const a[] = " a " ;
static constexpr char const b[] = " b " ;
using type = json_member_list<
json_number<a, int >,
json_number<b, int >
>;
};
static auto to_json_data ( Thing const & v ) {
return std::forward_as_tuple ( v. a , v. b );
}
} تم إرجاع ترتيب الأعضاء كحاجة إلى مطابقة التعيين في نوع type المستعار. يسمح هذا بتمرير نتيجة طرق الوصول أيضًا، إذا لم يكن أعضاء البيانات عامًا. أيضًا، يجب أن يكون الفصل Thing قابلاً للإنشاء من int, int . تدعم المكتبة كلاً من المُنشئات العادية والحرف الأولي التجميعي ( Thing{ int, int } و Thing( int, int ) ) في C++17.
to_json_data بإرجاع مجموعة من المراجع إلى أعضاء الكائن الموجودين، ولكن يمكنه إرجاع القيم المحسوبة أيضًا. ولا يسمح بمرور القيم r لأنها غالبًا ما تكون مؤقتة، وقد يؤدي ذلك إلى تصحيح الأخطاء عن بعد. ستؤكد المكتبة static_assert على هذا وتقترح تضمين <daw/daw_tuple_forward.h> واستدعاء daw::forward_nonrvalue_as_tuple( ... ) الذي يخزن المؤقتات ويعيد توجيه أنواع المراجع الأخرى. يعمل المحللون من خلال إنشاء كل وسيطة في مكانها عند استدعاء مُنشئ الفصل. يمكن ضبط موزعي الوسائط الفردية للظروف المحددة للبيانات (مثل النقطة العائمة والأرقام المتكاملة). ثم من خلال سمة النوع الخاصة بنا التي تحدد الوسائط اللازمة لإنشاء فئة C++ وترتيبها، يمكننا النظر إلى كل عضو في JSON. الآن نقوم ببناء القيمة بنتيجة كل محلل؛ مشابه لـ T{ parse<0, json_string<"name">>( data ), parse<1, json_number<"age", unsigned>>( data ), parse<json_number<2, "number>>( data )} بالنسبة لكل عضو، سيتم نقل دفق البيانات إلى الأمام حتى نجد العضو الذي نحتاج إلى تحليله، وتخزين المواقع المهتمة لتحليله لاحقًا. وتسمح لنا هذه العملية بتحليل الفئات الأخرى كأعضاء أيضًا json_class<"member_name", Type> نوع التعيين بحيث يجب على كل سمة تعيين أن تتعامل فقط مع أعضائها المحددين وليس تفاصيلهم. 
في السياقات غير المسماة، مثل القيمة الجذرية، وعناصر المصفوفة، وبعض أنواع القيم الأساسية، وقوائم العناصر المتغيرة حيث يكون الاسم no_name ، يمكن للمرء استخدام بعض أنواع بيانات C++ الأصلية بدلاً من أنواع تعيين JSON. يتضمن ذلك، عددًا صحيحًا، والنقطة العائمة، وbool، وstd::string، وstd::string_view، والحاويات الترابطية، وحاويات التسلسل، وأنواع الإعجاب الفارغة/الاختيارية والفئات المعينة مسبقًا.
على سبيل المثال، لتعيين مجموعة من السلاسل.
template <>
struct daw ::json::json_data_contract<MyType> {
using type = json_member_list<json_array< " member_name " , std::string>>;
}; يمكن للمرء استخدام vcpkg للحصول على أحدث إصدار، ويسمى المنفذ daw-json-link
find_package ( daw-json-link )
#...
target_link_libraries ( MyTarget daw::daw-json-link ) المكتبة عبارة عن رأس فقط ويمكن استنساخها مع تبعياتها، متبوعة بإضافة المجلدات include/ لكل منها إلى مسار التضمين الخاص بالمترجم
لاستخدام daw_json_link في مشاريع cmake الخاصة بك، فإن إضافة ما يلي من شأنه أن يسمح له بسحبه مع التبعيات:
include ( FetchContent )
FetchContent_Declare(
daw_json_link
GIT_REPOSITORY https://github.com/beached/daw_json_link
GIT_TAG release
)
FetchContent_MakeAvailable(daw_json_link)
#...
target_link_libraries ( MyTarget daw::daw-json-link )على نظام به bash، يكون الأمر مشابهًا للأنظمة الأخرى أيضًا، يمكن تثبيت ما يلي للنظام
git clone https://github.com/beached/daw_json_link
cd daw_json_link
mkdir build
cd build
cmake ..
cmake --install . سيسمح هذا بتثبيت cmake find_package أو استخدامه كرأس عادي طالما تم تضمين مجلد تضمين بادئة التثبيت في مسارات التضمين الخاصة بالمترجم
سيقوم ما يلي ببناء الاختبارات وتشغيلها.
git clone https://github.com/beached/daw_json_link
cd daw_json_link
mkdir build
cd build
cmake -DDAW_ENABLE_TESTING=On ..
cmake --build .
ctest . بعد الإنشاء، يمكن اختبار الأمثلة الفردية أيضًا. يتطلب city_test_bin المسار إلى ملف المدن JSON.
./tests/city_test_bin ../test_data/cities.jsonيجب أن يتطابق ترتيب الأعضاء في هياكل البيانات بشكل عام مع ترتيب بيانات JSON، إن أمكن. يكون المحلل اللغوي أسرع إذا لم يكن بحاجة إلى تتبع القيم. يمكن للقيم الاختيارية، عندما تكون مفقودة في بيانات JSON، أن تبطئ عملية التحليل أيضًا. إذا أمكن، أرسلها على أنها فارغة. لا يخصص المحلل اللغوي. قد يتم تحليل أنواع البيانات وهذا يسمح للشخص باستخدام مخصصات مخصصة أو مزيج حيث أن هياكل البيانات الخاصة بهم ستقوم بالتخصيص. الإعدادات الافتراضية للمصفوفات هي استخدام std::vector وإذا لم يكن ذلك مرغوبًا، فيجب عليك توفير النوع.

لا تقوم المكتبة حاليًا بإلغاء/إلغاء أسماء الأعضاء عند إجراء تسلسل، ومن المتوقع أن تكون صالحة وغير قابلة للإلغاء. قد تكون هذه إضافة اختيارية في المستقبل، حيث أن لها تكلفة.
هناك اختلافات طفيفة بين C++ 17 وC++ 20 حيث يسمح C++ 20 ببعض التعليمات البرمجية غير المتوفرة في C++ 17.
namespace daw ::json {
template <>
struct json_data_contract <MyType> {
static constexpr char const member_name[] = " memberName " ;
using type = json_member_list<json_number<member_name>>;
};
}يدعم كلا الإصدارين من C++ هذه الطريقة لتسمية الأعضاء.
عند التحويل البرمجي ضمن برنامج التحويل البرمجي C++20، بالإضافة إلى تمرير char const * كما هو الحال في C++17، يمكن تحديد أسماء الأعضاء كسلسلة حرفية مباشرة. لا يزال دعم برنامج التحويل البرمجي لـ C++ 20 مبكرًا حقًا وهنا تأتي التنانين. هناك مشكلات معروفة تتعلق بـ g++9.x في وضع C++20، وتم اختبارها فقط مع g++10/11. هنا يكون التنين
namespace daw ::json {
template <>
struct json_data_contract <MyType> {
using type = json_member_list<json_number< " member_name " >>;
};
} بمجرد تعيين نوع البيانات باستخدام json_data_contract ، توفر المكتبة طرقًا لتحليل JSON لهم
MyClass my_class = from_json<MyClass>( json_str );وبدلاً من ذلك، إذا كان الإدخال موثوقًا به، فيمكن أن يكون الإصدار الأقل فحصًا أسرع
MyClass my_class = from_json<MyClass, options::parse_flags<options::CheckedParseMode::no>>( json_str ); تستخدم مستندات JSON التي تحتوي على جذر الصفيف الدالة from_json_array للتحليل
std::vector<MyClass> my_data = from_json_array<MyClass>( json_str );وبدلاً من ذلك، إذا كان الإدخال موثوقًا به، فيمكن أن يكون الإصدار الأقل فحصًا أسرع
std::vector<MyClass> my_data = from_json_array<MyClass, std::vector<MyClass>, options::parse_flags<options::CheckedParseMode::no>>( json_str );json_array_iterator إذا كنت تريد العمل من بيانات مصفوفة JSON، فيمكنك الحصول على مكرر واستخدام خوارزميات std للتكرار عبر المصفوفة في بيانات JSON عبر json_array_iterator
using iterator_t = json_array_iterator<MyClass>;
auto pos = std::find( iterator_t ( json_str ), iterator_t ( ), MyClass( ... ) );وبدلاً من ذلك، إذا كان الإدخال موثوقًا، فيمكنك الاتصال بالإصدار الأقل فحصًا
using iterator_t = daw::json::json_array_iterator<MyClass, options::CheckedParseMode::no>;
auto pos = std::find( iterator_t ( json_str ), iterator_t ( ), MyClass( ... ) );json_value بالنسبة إلى DOM مثل واجهة برمجة التطبيقات (api)، والتي غالبًا ما تُستخدم لأشياء مثل واجهة المستخدم الرسومية (GUI) وتوفير التعليمات البرمجية عندما تكون التعيينات غير كافية، يمكن للمرء استخدام json_value . يتم استخدام هذا في أداة json_to_cpp.
auto jv = daw::json::json_value( json_doc );يمكن للمرء استخدام مسار JSON لاستخراج عدد صحيح
int foo = as< int >( jv[ " path.to.int " ] ); هنا، "path.to.int" هو مسار JSON الذي يمثل التنقيب في فئة JSON مثل
{
"path" : {
"to" : {
"int" : 5
}
}
} يمكن للمرء أيضًا الاختيار عبر مصفوفة مثل بناء الجملة في مسار JSON أيضًا، حيث سيحدد "path[5]" العنصر/العضو الخامس في "path" . إذا كنت تريد إجراء تسلسل إلى JSON. تعمل صيغة مسار JSON مع from_json و from_json_array و json_array_iterator أيضًا.
to_jsonstd::string my_json_data = to_json( MyClass{} ); أو إجراء تسلسل لمصفوفة أو مجموعة أو نطاق أو طريقة عرض للأشياء. يتطلب فقط std::begin(...) و std::end(...) للعمل مع النوع. يسمح هذا بالتسلسل عندما لا يكون النوع عبارة عن مجموعة قابلة للإنشاء من الأشياء.
std::vector<MyClass> arry = ...;
std::string my_json_data = to_json_array( arry ); يتم افتراضيًا طرح أخطاء التحليل daw::json::json_exception الذي يتضمن معلومات حول سبب الفشل وموقعه.
إذا تم تعطيل الاستثناءات، فستستدعي المكتبة std::terminate عند حدوث خطأ تحليلي افتراضيًا.
في حين أن التعامل مع الخطأ بشكل افتراضي هو رمي daw::json::json_exception على الأخطاء، أو استدعاء std::terminate إذا تم تعطيل الاستثناءات. يمكن للمرء تغيير هذا السلوك عن طريق تعيين مؤشر الوظيفة daw::json::daw_json_error_handler . الشرط الوحيد هو عدم إرجاع الوظيفة. أحد الأمثلة التي تستخدم هذا موجود في error_handling_bench_test.cpp
يمكن تعديل تدقيق الأخطاء على أساس التحليل. from_json و from_json_array و json_value و json_array_iterator وجميعها تدعم خيارات التحليل. يمكن توفير المكالمات خيار محلل. تم توثيق الخيارات المتاحة في عنصر كتاب الطبخ parser_policies.
daw::json::json_exception له وظيفة عضو std::string_view reason( ) const شبيهة بـ std::exception 's what( ) ولكنها تُرجع std::string بسياق أكثر مما يفعله what( ) . إذا كنت تريد تعطيل الاستثناءات في بيئة تحتوي عليها، فيمكنك تحديد DAW_JSON_DONT_USE_EXCEPTIONS لتعطيل طرح الاستثناءات بواسطة المكتبة أو تعيين المعالج، لم يعد هذا موصى به حيث يمكن تعيين المعالج على أحد الوضعين الافتراضيين daw::json::default_error_handling_throwing أو daw::json::default_error_handling_terminating .
يمكن تحقيق ذلك عن طريق كتابة تخصص json_data_contract في مساحة الاسم daw::json . على سبيل المثال:
# include < daw/json/daw_json_link.h >
# include < string >
# include < string_view >
# include < vector >
struct TestClass {
int i = 0 ;
double d = 0.0 ;
bool b = false ;
std::string s{};
std::vector< int > y{};
TestClass ( int Int, double Double, bool Bool, std::string S,
std::vector< int > Y)
: i(Int), d(Double), b(Bool), s(std::move( S ) ), y(std::move( Y )) {}
};
namespace daw ::json {
template <>
struct json_data_contract <TestClass> {
using type =
json_member_list<
json_number< " i " , int >,
json_number< " d " >,
json_bool< " b " >,
json_string< " s " >,
json_array< " y " , int >
>;
};
} // namespace daw::json
int main () {
std::string_view test_001_t_json_data = R"( {
"i":5,
"d":2.2e4,
"b":false,
"s":"hello world",
"y":[1,2,3,4]
} )" ;
std::string_view json_array_data = R"( [{
"i":5,
"d":2.2e4,
"b":false,
"s":"hello world",
"y":[1,2,3,4]
},{
"i":4,
"d":122e4,
"b":true,
"s":"goodbye world",
"y":[4,3,1,4]
}] )" ;
TestClass test_class = daw::json::from_json<TestClass>(test_001_t_json_data);
std::vector<TestClass> arry_of_test_class =
daw::json::from_json_array<TestClass>(test_001_t_json_data);
}انظر على مستكشف المترجم
يتم دعم كل من المنشئات المجمعة والمستخدمين. يوفر الوصف القيم اللازمة لإنشاء النوع والترتيب الخاص بك. الترتيب المحدد هو الترتيب الذي تم وضعه في المنشئ. توجد نقاط تخصيص لتوفير طريقة لإنشاء النوع الخاص بك أيضًا. فئة مثل:
# include < daw/json/daw_json_link.h >
struct AggClass {
int a{};
double b{};
};
namespace daw ::json {
template <>
struct json_data_contract <AggClass> {
using type = json_member_list<
json_number< " a " , int >,
json_number< " b " >
>;
};
}يعمل أيضا. نفس الشيء ولكن C++ 17
# include < daw/json/daw_json_link.h >
struct AggClass {
int a{};
double b{};
};
namespace daw ::json {
template <>
struct json_data_contract <AggClass> {
static inline constexpr char const a[] = " a " ;
static inline constexpr char const b[] = " b " ;
using type = json_member_list<
json_number<a, int >,
json_number<b>
>;
};
} أوصاف الفصل متكررة مع أعضائها الفرعيين. باستخدام AggClass السابق يمكن للمرء إدراجه كعضو في فئة أخرى
// See above for AggClass
struct MyClass {
AggClass other;
std::string_view some_name;
};
namespace daw ::json {
template <>
struct json_data_contract <MyClass> {
using type = json_member_list<
json_class< " other " , AggClass>,
json_string< " id " , std::string_view>
>;
};
} ما ورد أعلاه يعين فئة MyClass التي تحتوي على فئة أخرى موصوفة AggClass. يمكنك أيضًا أن ترى أن أسماء أعضاء فئة C++ ليس من الضروري أن تتطابق مع أسماء JSON المعينة وأن السلاسل يمكن أن تستخدم std::string_view كنوع النتيجة. يعد هذا تحسينًا مهمًا للأداء إذا كان بإمكانك ضمان وجود المخزن المؤقت الذي يحتوي على ملف JSON طوال فترة وجود الفصل.
التكرار عبر صفائف JSON. مكرر الإدخال daw::json::json_array_iterator<JsonElement> يسمح لأحد بالتكرار عبر مجموعة عناصر JSON. إنه مكرر إدخال من الناحية الفنية ولكن يمكن تخزينه وإعادة استخدامه مثل مكرر أمامي. لا يُرجع مرجعًا بل قيمة.
# include < daw/json/daw_json_link.h >
# include < daw/json/daw_json_iterator.h >
# include < iostream >
struct AggClass {
int a{};
double b{};
};
namespace daw ::json {
template <>
struct json_data_contract <AggClass> {
using type = json_member_list<
json_number< " a " , int >,
json_number< " b " >
>;
};
} // namespace daw::json
int main () {
std::string json_array_data = R"( [
{"a":5,"b":2.2},
{"a":5,"b":3.14},
{"a":5,"b":0.122e44},
{"a":5334,"b":34342.2}
] )" ;
using iterator_t = daw::json::json_array_iterator<AggClass>;
auto pos =
std::find_if (
iterator_t (json_array_data),
iterator_t (),
[](AggClass const &element) {
return element. b > 1000.0 ;
}
);
if (pos == iterator_t ()) {
std::cout << " Not found n " ;
} else {
std::cout << " Found n " ;
}
} يمكن أن يبدأ التحليل عند عضو أو عنصر محدد. يمكن تحديد مسار عضو اختياري إلى from_json و from_json_array و json_value و json_array_iterator وما شابه. التنسيق عبارة عن قائمة مفصولة بنقاط لأسماء الأعضاء واختياريًا فهرس مصفوفة مثل member0.member1 والذي يشبه التحليل من:
{
"member0" : {
"member1" : {}
}
} أو member0[5].member1 والذي سيبدأ التحليل عند " member1 " في مستند مثل:
{
"member0" : [
" a " ,
" b " ,
" c " ,
" d " ,
" e " ,
{
"member1" : " "
}
]
}أو
{
"member0" : {
"a" : " " ,
"b" : " " ,
"c" : " " ,
"d" : " " ,
"e" : " " ,
"f" : {
"member1" : " "
}
}
}يتم دعم التعليقات عند استخدام سياسة المحلل اللغوي الخاصة بها. يوجد حاليًا شكلان من سياسات التعليق.
// تعليقات السطر ونمط C /* */ تعليقات. { // This is a comment
"a" /*this is also a comment*/: "a's value"
}
# تعليقات السطر { # This is a comment
"a" #this is also a comment
: "a's value"
}
يمكن ضبط سياسة التعليق عبر PolicyCommentTypes . راجع parser_policies لمزيد من المعلومات.
لتمكين التسلسل، يجب على المرء إنشاء وظيفة ثابتة إضافية في تخصصك لـ json_data_contract تسمى to_json_data( Thing const & ); التي ترجع مجموعة من الأعضاء. سيوفر تعيينًا من النوع الخاص بك إلى الوسائط المتوفرة في وصف الفصل. لإجراء تسلسل إلى سلسلة JSON، يتم استدعاء to_json( my_thing ); حيث my_thing هو نوع مسجل أو أحد الأنواع الأساسية مثل الحاويات والخرائط والسلاسل والمنطق والأرقام. نتيجة الطريقة الثابتة to_json_data( Thing const & ) هي tuple تتطابق عناصره مع الترتيب في type الاسم المستعار لنوع json_data_contract المصاحب. نظرًا للطريقة التي يتم بها استخدام الطريقة، فإن الصفوف التي تحتوي على عناصر rvalue ستؤدي إلى خطأ في الاستخدام بعد التدمير. سوف يخطئ المترجم إذا حدث هذا. سيؤدي تضمين <daw/daw_tuple_forward.h> والطريقة daw::forward_nonrvalue_as_tuple بدلاً من ذلك إلى تخزين قيم r بدلاً من تمريرها حسب المرجع. غالبًا ما يكون ذلك نتيجة لعناصر الصف المحسوبة. يتيح لك استخدام المثال أعلاه إضافة طريقة to_json_data
# include < daw/json/daw_json_link.h >
# include < tuple >
struct AggClass {
int a;
double b;
};
namespace daw ::json {
template <>
struct json_data_contract <AggClass> {
using type = json_member_list<
json_number< " a " , int >,
json_number< " b " >
>;
static constexpr auto to_json_data ( AggClass const & value ) {
return std::forward_as_tuple ( value. a , value. b );
}
};
}
// ...
AggData value = // ...;
std::string test_001_t_json_data = to_json( value );
// or
std::vector<AggData> values = // ...;
std::string json_array_data = to_json_array( values ); بدلاً من ذلك، يمكن للمرء الإخراج إلى أي نوع WritableOutput، يتضمن هذا افتراضيًا FILE* وiostreams وحاويات الأحرف ومؤشرات الأحرف. في json_data_constract من النوع الخاص بك. أو في حالة الاشتراك، يمكن للمرء الحصول على عامل تشغيل ostream << لنوعه الذي يقوم بإدراج json في دفق الإخراج عن طريق إضافة اسم مستعار للنوع يسمى opt_into_iostreams ، ولا يهم النوع الذي يطلق عليه الاسم المستعار، ويتضمن daw/json/daw_json_iostream.h . على سبيل المثال
# include < daw/json/daw_json_link.h >
# include < daw/json/daw_json_iostream.h >
# include < tuple >
struct AggClass {
int a{};
double b{};
};
namespace daw ::json {
template <>
struct json_data_contract <AggClass> {
using opt_into_iostreams = void ;
using type = json_member_list<
json_number< " a " , int >,
json_number< " b " >
>;
static inline auto to_json_data ( AggClass const & value ) {
return std::forward_as_tuple ( value. a , value. b );
}
};
}
// ...
AggData value = // ...;
std::cout << value << ' n ' ;
// or
std::vector<AggData> values = // ...;
std::cout << values << ' n ' ;يمكن العثور على مثال عملي على daw_json_iostream_test.cpp أو على مستكشف المترجم
error: pointer to subobject of string literal is not allowed in a template argument constexpr char const member_name[] = " member_name " ;
// ...
json_link<member_name, Type>هناك بعض التعريفات التي تؤثر على كيفية عمل JSON Link
DAW_JSON_DONT_USE_EXCEPTIONS - يتحكم في السماح بالاستثناءات. إذا لم تكن كذلك، فستحدث std::terminate() على الأخطاء. يكون هذا تلقائيًا إذا تم تعطيل الاستثناءات (على سبيل المثال -fno-exceptions )DAW_ALLOW_SSE42 - السماح بوضع SSE42 التجريبي، ويكون وضع constexpr بشكل عام أسرعDAW_JSON_NO_CONST_EXPR - يمكن استخدام هذا للسماح بإنشاء الفئات بدون نقل/نسخ الأعضاء الخاصين من بيانات JSON قبل C++ 20. لا يعمل هذا الوضع في تعبير ثابت قبل C++ 20 عندما لم تعد هناك حاجة إلى هذه العلامة. ربما لا تزال المترجمات الأقدم تعمل ولكن في اختبار بعضها أدى إلى حدوث أخطاء في ICE أو أخطاء في الترجمة بسبب دعم C++ 17 الذي يحتوي على أخطاء. في كثير من الأحيان عدم استخدام constexpr يمكن أن يساعد أيضًا.
json_key_value .std::multimap<std::string, T> أو std::vector<std::pair<std::string, T>> يتم الاحتفاظ بجميع الأعضاء بالترتيب السابق. وبدلاً من ذلك، سيسمح النوع json_value بالتكرار على أعضاء الفصل والتحليل البطيء للعضو الصحيح. راجع القيم الأساسية لكتاب الطبخ والتي توضح هذه الطرق.