Salah satu perpustakaan JSON tercepat di dunia. Glaze membaca dan menulis dari memori objek, menyederhanakan antarmuka dan menawarkan kinerja luar biasa.
Glasir juga mendukung:
Murni, kompilasi refleksi waktu untuk struct
Kepatuhan JSON RFC 8259 dengan validasi UTF-8
Dukungan perpustakaan C++ standar
Hanya tajuk
Langsung ke serialisasi/deserialisasi memori
Kompilasi peta waktu dengan pencarian waktu konstan dan hashing sempurna
Pembungkus yang kuat untuk mengubah perilaku baca/tulis (Wrapper)
Gunakan fungsi baca/tulis khusus Anda sendiri (Baca/Tulis Khusus)
Tangani kunci yang tidak dikenal dengan cara yang cepat dan fleksibel
Akses memori langsung melalui sintaks penunjuk JSON
Data biner melalui API yang sama untuk performa maksimal
Tidak ada pengecualian (dikompilasi dengan -fno-exceptions
)
Tidak diperlukan informasi jenis runtime (kompilasi dengan -fno-rtti
)
Penanganan kesalahan cepat dengan hubungan arus pendek
Dukungan JSON-RPC 2.0
Pembuatan Skema JSON
Sangat portabel, menggunakan SWAR (SIMD Within A Register) yang dioptimalkan dengan cermat untuk kompatibilitas luas
Dukungan Baca Sebagian dan Tulis Sebagian
Membaca/Menulis CSV
Lebih banyak lagi!
Lihat DOCS untuk dokumentasi lebih lanjut.
Perpustakaan | Waktu Pulang Pergi | Tulis (MB/dtk) | Baca (MB/dtk) |
---|---|---|---|
Mengacai | 1.04 | 1366 | 1224 |
simdjson (sesuai permintaan) | T/A | T/A | 1198 |
yyjson | 1.23 | 1005 | 1107 |
daw_json_link | 2.93 | 365 | 553 |
RapidJSON | 3.65 | 290 | 450 |
Boost.JSON (langsung) | 4.76 | 199 | 447 |
json_struct | 5.50 | 182 | 326 |
nlohmann | 15.71 | 84 | 80 |
Kode uji kinerja tersedia di sini
Peringatan kinerja: simdjson dan yyjson bagus, tetapi mereka mengalami penurunan kinerja yang besar ketika data tidak berada dalam urutan yang diharapkan atau kunci apa pun hilang (masalah bertambah seiring bertambahnya ukuran file, karena mereka harus mengulanginya melalui dokumen).
Selain itu, simdjson dan yyjson tidak mendukung penanganan string yang lolos secara otomatis, jadi jika salah satu string yang saat ini tidak lolos dalam tolok ukur ini mengandung escape, escape tersebut tidak akan ditangani.
Tes ABC menunjukkan bagaimana simdjson memiliki kinerja yang buruk ketika kunci tidak berada dalam urutan yang diharapkan:
Perpustakaan | Baca (MB/dtk) |
---|---|
Mengacai | 678 |
simdjson (sesuai permintaan) | 93 |
Spesifikasi biner yang diberi tag: BEVE
Metrik | Waktu Pulang Pergi | Tulis (MB/dtk) | Baca (MB/dtk) |
---|---|---|---|
Performa mentah | 0,42 | 3235 | 2468 |
Data JSON yang setara* | 0,42 | 3547 | 2706 |
Ukuran JSON: 670 byte
Ukuran BEVE: 611 byte
*BEVE dikemas lebih efisien dibandingkan JSON, sehingga pengiriman data yang sama menjadi lebih cepat.
Struktur Anda akan secara otomatis tercermin! Tidak ada metadata yang diperlukan oleh pengguna.
struct my_struct
{
int i = 287 ;
double d = 3.14 ;
std::string hello = " Hello World " ;
std::array< uint64_t , 3 > arr = { 1 , 2 , 3 };
std::map<std::string, int > map{{ " one " , 1 }, { " two " , 2 }};
};
JSON (dipercantik)
{
"i" : 287 ,
"d" : 3.14 ,
"hello" : " Hello World " ,
"arr" : [
1 ,
2 ,
3
],
"map" : {
"one" : 1 ,
"two" : 2
}
}
Tulis JSON
my_struct s{};
std::string buffer = glz::write_json(s).value_or( " error " );
atau
my_struct s{};
std::string buffer{};
auto ec = glz::write_json(s, buffer);
if (ec) {
// handle error
}
Baca JSON
std::string buffer = R"( {"i":287,"d":3.14,"hello":"Hello World","arr":[1,2,3],"map":{"one":1,"two":2}} )" ;
auto s = glz::read_json<my_struct>(buffer);
if (s) // check std::expected
{
s. value (); // s.value() is a my_struct populated from buffer
}
atau
std::string buffer = R"( {"i":287,"d":3.14,"hello":"Hello World","arr":[1,2,3],"map":{"one":1,"two":2}} )" ;
my_struct s{};
auto ec = glz::read_json(s, buffer); // populates s from buffer
if (ec) {
// handle error
}
auto ec = glz::read_file_json(obj, " ./obj.json " , std::string{});
auto ec = glz::write_file_json(obj, " ./obj.json " , std::string{});
Penting
Nama file (argumen ke-2), harus diakhiri dengan null.
Tindakan dibuat dan diuji dengan Clang (17+), MSVC (2022), dan GCC (12+) di apple, windows, dan linux.
Glaze berupaya menjaga kompatibilitas dengan tiga versi terbaru GCC dan Clang, serta versi terbaru MSVC dan Apple Clang.
Glaze memerlukan pra-prosesor yang sesuai dengan standar C++, yang memerlukan tanda /Zc:preprocessor
saat membangun dengan MSVC.
CMake memiliki opsi glaze_ENABLE_AVX2
. Ini akan mencoba menggunakan instruksi SIMD AVX2
dalam beberapa kasus untuk meningkatkan kinerja, selama sistem yang Anda konfigurasi mendukungnya. Setel opsi ini ke OFF
untuk menonaktifkan set instruksi AVX2, seperti jika Anda melakukan kompilasi silang untuk Arm. Jika Anda tidak menggunakan CMake, makro GLZ_USE_AVX2
mengaktifkan fitur tersebut jika ditentukan.
include (FetchContent)
FetchContent_Declare(
glaze
GIT_REPOSITORY https://github.com/stephenberry/glaze.git
GIT_TAG main
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(glaze)
target_link_libraries ( ${PROJECT_NAME} PRIVATE glaze::glaze)
find_package(glaze REQUIRED)
target_link_libraries(main PRIVATE glaze::glaze)
import libs = libglaze%lib{glaze}
Jika Anda ingin mengkhususkan refleksi Anda maka Anda dapat menulis kode di bawah ini:
Metadata ini juga diperlukan untuk struct non-agregat yang dapat diinisialisasi.
template <>
struct glz ::meta<my_struct> {
using T = my_struct;
static constexpr auto value = object(
&T::i,
&T::d,
&T::hello,
&T::arr,
&T::map
);
};
struct my_struct
{
int i = 287 ;
double d = 3.14 ;
std::string hello = " Hello World " ;
std::array< uint64_t , 3 > arr = { 1 , 2 , 3 };
std::map<std::string, int > map{{ " one " , 1 }, { " two " , 2 }};
struct glaze {
using T = my_struct;
static constexpr auto value = glz::object(
&T::i,
&T::d,
&T::hello,
&T::arr,
&T::map
);
};
};
Saat Anda menentukan metadata Glaze, objek akan secara otomatis mencerminkan nama non-statis dari penunjuk objek anggota Anda. Namun, jika Anda menginginkan nama khusus atau mendaftarkan fungsi lambda atau wrapper yang tidak memberikan nama untuk bidang Anda, Anda dapat menambahkan nama bidang di metadata Anda secara opsional.
Contoh nama khusus:
template <>
struct glz ::meta<my_struct> {
using T = my_struct;
static constexpr auto value = object(
" integer " , &T::i,
" double " , &T::d,
" string " , &T::hello,
" array " , &T::arr,
" my map " , &T::map
);
};
Masing-masing string ini bersifat opsional dan dapat dihapus untuk masing-masing bidang jika Anda ingin namanya tercermin.
Nama diperlukan untuk:
- variabel anggota constexpr statis
- Pembungkus
- Fungsi Lambda
Glaze menyediakan API refleksi waktu kompilasi yang dapat dimodifikasi melalui spesialisasi glz::meta
. API refleksi ini menggunakan refleksi murni kecuali jika spesialisasi glz::meta
disediakan, dalam hal ini perilaku default akan diganti oleh pengembang.
static_assert (glz::reflect<my_struct>::size == 5 ); // Number of fields
static_assert (glz::reflect<my_struct>::keys[ 0 ] == " i " ); // Access keys
Peringatan
Bidang glz::reflect
yang dijelaskan di atas telah diformalkan dan kemungkinan besar tidak akan berubah. Bidang lain dalam struct glz::reflect
dapat berkembang seiring kami terus memformalkan spesifikasi. Oleh karena itu, perubahan yang dapat menyebabkan gangguan dapat terjadi pada bidang yang tidak terdokumentasikan di masa mendatang.
Membaca dan menulis khusus dapat dicapai melalui pendekatan spesialisasi to
/ from
yang kuat, yang dijelaskan di sini: custom-serialization.md. Namun, ini hanya berfungsi untuk tipe yang ditentukan pengguna.
Untuk kasus penggunaan umum atau kasus di mana variabel anggota tertentu harus memiliki pembacaan dan penulisan khusus, Anda dapat menggunakan glz::custom
untuk mendaftarkan fungsi anggota baca/tulis, std::fungsi, atau fungsi lambda.
struct custom_encoding
{
uint64_t x{};
std::string y{};
std::array< uint32_t , 3 > z{};
void read_x ( const std::string& s) {
x = std::stoi (s);
}
uint64_t write_x () {
return x;
}
void read_y ( const std::string& s) {
y = " hello " + s;
}
auto & write_z () {
z[ 0 ] = 5 ;
return z;
}
};
template <>
struct glz ::meta<custom_encoding>
{
using T = custom_encoding;
static constexpr auto value = object( " x " , custom<&T::read_x, &T::write_x>, //
" y " , custom<&T::read_y, &T::y>, //
" z " , custom<&T::z, &T::write_z>);
};
suite custom_encoding_test = [] {
" custom_reading " _test = [] {
custom_encoding obj{};
std::string s = R"( {"x":"3","y":"world","z":[1,2,3]} )" ;
expect (! glz::read_json (obj, s));
expect (obj. x == 3 );
expect (obj. y == " helloworld " );
expect (obj. z == std::array< uint32_t , 3 >{ 1 , 2 , 3 });
};
" custom_writing " _test = [] {
custom_encoding obj{};
std::string s = R"( {"x":"3","y":"world","z":[1,2,3]} )" ;
expect (! glz::read_json (obj, s));
std::string out{};
expect ( not glz::write_json (obj, out));
expect (out == R"( {"x":3,"y":"helloworld","z":[5,2,3]} )" );
};
};
Saat menggunakan pointer anggota (misalnya &T::a
) struktur kelas C++ harus cocok dengan antarmuka JSON. Mungkin diinginkan untuk memetakan kelas C++ dengan tata letak berbeda ke antarmuka objek yang sama. Hal ini dicapai melalui mendaftarkan fungsi lambda alih-alih penunjuk anggota.
template <>
struct glz ::meta<Thing> {
static constexpr auto value = object(
" i " , []( auto && self) -> auto & { return self. subclass . i ; }
);
};
Nilai self
yang diteruskan ke fungsi lambda akan menjadi objek Thing
, dan fungsi lambda memungkinkan kita membuat subkelas tidak terlihat oleh antarmuka objek.
Fungsi Lambda secara default adalah pengembalian salinan, oleh karena itu tipe pengembalian auto&
biasanya diperlukan agar glasir dapat menulis ke memori.
Perhatikan bahwa pemetaan ulang juga dapat dicapai melalui petunjuk/referensi, karena glasir memperlakukan nilai, petunjuk, dan referensi dengan cara yang sama saat menulis/membaca.
Sebuah kelas dapat diperlakukan sebagai nilai dasar sebagai berikut:
struct S {
int x{};
};
template <>
struct glz ::meta<S> {
static constexpr auto value{ &S::x };
};
atau menggunakan lambda:
template <>
struct glz ::meta<S> {
static constexpr auto value = []( auto & self) -> auto & { return self. x ; };
};
Glaze aman digunakan dengan pesan yang tidak tepercaya. Kesalahan dikembalikan sebagai kode kesalahan, biasanya dalam glz::expected
, yang berperilaku seperti std::expected
.
Glaze berfungsi untuk menangani kesalahan hubung singkat, yang berarti penguraian keluar dengan sangat cepat jika ditemukan kesalahan.
Untuk menghasilkan pesan kesalahan yang lebih bermanfaat, panggil format_error
:
auto pe = glz::read_json(obj, buffer);
if (pe) {
std::string descriptive_error = glz::format_error (pe, buffer);
}
Kasus uji ini:
{ "Hello" : " World " x, "color": "red" }
Menghasilkan kesalahan ini:
1:17: expected_comma
{"Hello":"World"x, "color": "red"}
^
Menunjukkan bahwa x tidak valid di sini.
std::string
non-const direkomendasikan untuk buffer input, karena hal ini memungkinkan Glaze meningkatkan kinerja dengan padding sementara dan buffer akan dihentikan null.
Secara default, opsi null_terminated
disetel ke true
dan buffer yang diakhiri dengan null harus digunakan saat mengurai JSON. Opsi ini dapat dimatikan dengan sedikit penurunan kinerja, yang memungkinkan buffer yang dihentikan non-null:
constexpr glz::opts options{. null_terminated = false };
auto ec = glz::read<options>(value, buffer); // read in a non-null terminated buffer
Pengakhiran nol tidak diperlukan saat mengurai BEVE (biner). Tidak ada perbedaan dalam kinerja.
Peringatan
Saat ini, null_terminated = false
tidak valid untuk penguraian CSV dan buffer harus diakhiri dengan null.
Jenis array secara logis dikonversi ke nilai array JSON. Konsep digunakan untuk mengizinkan berbagai wadah dan bahkan wadah pengguna jika cocok dengan antarmuka perpustakaan standar.
glz::array
(waktu kompilasi tipe campuran)std::tuple
(waktu kompilasi tipe campuran)std::array
std::vector
std::deque
std::list
std::forward_list
std::span
std::set
std::unordered_set
Jenis objek secara logis dikonversi ke nilai objek JSON, seperti peta. Seperti JSON, Glaze memperlakukan definisi objek sebagai peta tidak berurutan. Oleh karena itu urutan tata letak objek tidak harus cocok dengan urutan biner yang sama di C++.
glz::object
(waktu kompilasi tipe campuran)std::map
std::unordered_map
std::pair
(mengaktifkan kunci dinamis dalam penyimpanan tumpukan)
std::pair
ditangani sebagai objek dengan kunci dan nilai tunggal, tetapi ketikastd::pair
digunakan dalam array, Glaze menggabungkan pasangan tersebut menjadi satu objek.std::vector<std::pair<...>>
akan diserialkan sebagai objek tunggal. Jika Anda tidak ingin perilaku ini atur opsi waktu kompilasi.concatenate = false
.
std::variant
Lihat Penanganan Varian untuk informasi lebih lanjut.
std::unique_ptr
std::shared_ptr
std::optional
Tipe nullable dapat dialokasikan dengan input yang valid atau dibatalkan dengan kata kunci null
.
std::unique_ptr< int > ptr{};
std::string buffer{};
expect ( not glz::write_json (ptr, buffer));
expect (buffer == " null " );
expect ( not glz::read_json (ptr, " 5 " ));
expect (*ptr == 5 );
buffer.clear();
expect ( not glz::write_json (ptr, buffer));
expect (buffer == " 5 " );
expect ( not glz::read_json (ptr, " null " ));
expect (! bool (ptr));
Secara default enum akan ditulis dan dibaca dalam bentuk integer. Tidak diperlukan glz::meta
jika ini adalah perilaku yang diinginkan.
Namun, jika Anda lebih suka menggunakan enum sebagai string di JSON, enum dapat didaftarkan di glz::meta
sebagai berikut:
enum class Color { Red, Green, Blue };
template <>
struct glz ::meta<Color> {
using enum Color;
static constexpr auto value = enumerate(Red,
Green,
Blue
);
};
Sedang digunakan:
Color color = Color::Red;
std::string buffer{};
glz::write_json (color, buffer);
expect (buffer == " " Red " " );
Komentar didukung dengan spesifikasi yang ditentukan di sini: JSONC
Dukungan baca untuk komentar disediakan dengan glz::read_jsonc
atau glz::read<glz::opts{.comments = true}>(...)
.
JSON yang diformat dapat ditulis langsung melalui opsi waktu kompilasi:
auto ec = glz::write<glz::opts{. prettify = true }>(obj, buffer);
Atau, teks JSON dapat diformat dengan fungsi glz::prettify_json
:
std::string buffer = R"( {"i":287,"d":3.14,"hello":"Hello World","arr":[1,2,3]} )" );
auto beautiful = glz::prettify_json(buffer);
beautiful
sekarang:
{
"i" : 287 ,
"d" : 3.14 ,
"hello" : " Hello World " ,
"arr" : [
1 ,
2 ,
3
]
}
Untuk menulis JSON yang diperkecil:
auto ec = glz::write_json(obj, buffer); // default is minified
Untuk memperkecil panggilan teks JSON:
std::string minified = glz::minify_json(buffer);
Jika Anda ingin memerlukan JSON yang diperkecil atau mengetahui masukan Anda akan selalu diperkecil, Anda dapat memperoleh kinerja yang lebih baik dengan menggunakan opsi waktu kompilasi .minified = true
.
auto ec = glz::read<glz::opts{. minified = true }>(obj, buffer);
Glaze mendukung pendaftaran sekumpulan flag boolean yang berperilaku sebagai array opsi string:
struct flags_t {
bool x{ true };
bool y{};
bool z{ true };
};
template <>
struct glz ::meta< flags_t > {
using T = flags_t ;
static constexpr auto value = flags( " x " , &T::x, " y " , &T::y, " z " , &T::z);
};
Contoh:
flags_t s{};
expect (glz::write_json(s) == R"([ " x " , " z " ])");
Hanya "x"
dan "z"
yang ditulis, karena benar. Membaca di buffer akan menyetel boolean yang sesuai.
Saat menulis BEVE,
flags
hanya menggunakan satu bit per boolean (selaras byte).
Terkadang Anda hanya ingin menulis struktur JSON dengan cepat seefisien mungkin. Glaze menyediakan struktur mirip tupel yang memungkinkan Anda menumpuk struktur alokasi untuk menulis JSON dengan kecepatan tinggi. Struktur ini diberi nama glz::obj
untuk objek dan glz::arr
untuk array.
Di bawah ini adalah contoh pembuatan objek, yang juga berisi array, dan menuliskannya.
auto obj = glz::obj{ " pi " , 3.14 , " happy " , true , " name " , " Stephen " , " arr " , glz::arr{ " Hello " , " World " , 2 }};
std::string s{};
expect ( not glz::write_json (obj, s));
expect (s == R"( {"pi":3.14,"happy":true,"name":"Stephen","arr":["Hello","World",2]} )" );
Pendekatan ini jauh lebih cepat daripada
glz::json_t
untuk JSON generik. Namun, mungkin tidak cocok untuk semua konteks.
glz::merge
memungkinkan pengguna untuk menggabungkan beberapa tipe objek JSON menjadi satu objek.
glz::obj o{ " pi " , 3.141 };
std::map<std::string_view, int > map = {{ " a " , 1 }, { " b " , 2 }, { " c " , 3 }};
auto merged = glz::merge{o, map};
std::string s{};
glz::write_json (merged, s); // will write out a single, merged object
// s is now: {"pi":3.141,"a":0,"b":2,"c":3}
glz::merge
menyimpan referensi ke nilai untuk menghindari salinan
Lihat JSON Generik untuk glz::json_t
.
glz:: json_t json{};
std::string buffer = R"( [5,"Hello World",{"pi":3.14}] )" ;
glz::read_json (json, buffer);
assert (json[ 2 ][ " pi " ].get< double >() == 3.14);
Glaze menulis ke std::string
sama cepatnya dengan menulis ke buffer char mentah. Jika Anda memiliki alokasi ruang yang cukup di buffer, Anda dapat menulis ke buffer mentah, seperti yang ditunjukkan di bawah, namun hal ini tidak disarankan.
glz::read_json(obj, buffer);
const auto n = glz::write_json(obj, buffer.data()).value_or(0);
buffer.resize(n);
Struktur glz::opts
mendefinisikan pengaturan opsional waktu kompilasi untuk membaca/menulis.
Daripada memanggil glz::read_json(...)
, Anda bisa memanggil glz::read<glz::opts{}>(...)
dan menyesuaikan opsinya.
Misalnya: glz::read<glz::opts{.error_on_unknown_keys = false}>(...)
akan mematikan kesalahan pada kunci yang tidak diketahui dan melewatkan item dengan mudah.
glz::opts
juga dapat beralih antar format:
glz::read<glz::opts{.format = glz::BEVE}>(...)
-> glz::read_beve(...)
glz::read<glz::opts{.format = glz::JSON}>(...)
-> glz::read_json(...)
Struktur di bawah ini menunjukkan opsi yang tersedia dan perilaku default.
struct opts {
uint32_t format = json;
bool comments = false ; // Support reading in JSONC style comments
bool error_on_unknown_keys = true ; // Error when an unknown key is encountered
bool skip_null_members = true ; // Skip writing out params in an object if the value is null
bool use_hash_comparison = true ; // Will replace some string equality checks with hash checks
bool prettify = false ; // Write out prettified JSON
bool minified = false ; // Require minified input for JSON, which results in faster read performance
char indentation_char = ' ' ; // Prettified JSON indentation char
uint8_t indentation_width = 3 ; // Prettified JSON indentation size
bool new_lines_in_arrays = true ; // Whether prettified arrays should have new lines for each element
bool shrink_to_fit = false ; // Shrinks dynamic containers to new size to save memory
bool write_type_info = true ; // Write type info for meta objects in variants
bool error_on_missing_keys = false ; // Require all non nullable keys to be present in the object. Use
// skip_null_members = false to require nullable members
bool error_on_const_read =
false ; // Error if attempt is made to read into a const value, by default the value is skipped without error
bool validate_skipped = false ; // If full validation should be performed on skipped values
bool validate_trailing_whitespace =
false ; // If, after parsing a value, we want to validate the trailing whitespace
uint8_t layout = rowwise; // CSV row wise output/input
// The maximum precision type used for writing floats, higher precision floats will be cast down to this precision
float_precision float_max_write_precision{};
bool bools_as_numbers = false ; // Read and write booleans with 1's and 0's
bool quoted_num = false ; // treat numbers as quoted or array-like types as having quoted numbers
bool number = false ; // read numbers as strings and write these string as numbers
bool raw = false ; // write out string like values without quotes
bool raw_string =
false ; // do not decode/encode escaped characters for strings (improves read/write performance)
bool structs_as_arrays = false ; // Handle structs (reading/writing) without keys, which applies
bool allow_conversions = true ; // Whether conversions between convertible types are
// allowed in binary, e.g. double -> float
bool partial_read =
false ; // Reads into only existing fields and elements and then exits without parsing the rest of the input
// glaze_object_t concepts
bool partial_read_nested = false ; // Advance the partially read struct to the end of the struct
bool concatenate = true ; // Concatenates ranges of std::pair into single objects when writing
bool hide_non_invocable =
true ; // Hides non-invocable members from the cli_menu (may be applied elsewhere in the future)
};
Banyak dari opsi waktu kompilasi ini memiliki pembungkus untuk menerapkan opsi hanya pada satu bidang. Lihat Pembungkus untuk lebih jelasnya.
Secara default, Glaze sepenuhnya sesuai dengan standar JSON terbaru kecuali dalam dua kasus dengan opsi terkait:
validate_skipped
Opsi ini melakukan validasi JSON penuh untuk nilai yang dilewati saat penguraian. Ini tidak disetel secara default karena nilai biasanya dilewati ketika pengguna tidak mempedulikannya, dan Glaze masih memvalidasi untuk masalah besar. Namun, ini membuat lompatan lebih cepat dengan tidak peduli apakah nilai yang dilewati benar-benar sesuai dengan JSON. Misalnya, secara default Glaze akan memastikan angka yang dilewati memiliki semua karakter numerik yang valid, namun Glaze tidak akan memvalidasi masalah seperti angka nol di awal angka yang dilewati kecuali validate_skipped
aktif. Di mana pun Glaze mengurai nilai yang akan digunakan, nilai tersebut divalidasi sepenuhnya.validate_trailing_whitespace
Opsi ini memvalidasi spasi tambahan dalam dokumen yang diurai. Karena Glaze mem-parsing struct C++, biasanya tidak perlu melanjutkan parsing setelah objek yang diinginkan dibaca. Aktifkan opsi ini jika Anda ingin memastikan bahwa sisa dokumen memiliki spasi yang valid, jika tidak, Glaze akan mengabaikan konten setelah konten yang diinginkan diurai. Catatan
Glaze tidak secara otomatis melakukan unicode karakter kontrol escape (misalnya "x1f"
hingga "u001f"
), karena hal ini menimbulkan risiko menyematkan karakter null dan karakter tak kasat mata lainnya dalam string. Opsi waktu kompilasi akan ditambahkan untuk mengaktifkan konversi ini (masalah terbuka: unicode lolos penulisan), tetapi ini tidak akan menjadi perilaku default.
Akan berguna untuk mengetahui keberadaan kunci dalam suatu objek untuk mencegah kesalahan, namun nilainya mungkin tidak diperlukan atau tidak ada di C++. Kasus-kasus ini ditangani dengan mendaftarkan tipe glz::skip
dengan meta data.
struct S {
int i{};
};
template <>
struct glz ::meta<S> {
static constexpr auto value = object( " key_to_skip " , skip{}, &S::i);
};
std::string buffer = R"( {"key_to_skip": [1,2,3], "i": 7} )" ;
S s{};
glz::read_json (s, buffer);
// The value [1,2,3] will be skipped
expect (s.i == 7 ); // only the value i will be read into
Glaze dirancang untuk membantu membangun API generik. Terkadang suatu nilai perlu diekspos ke API, namun tidak diinginkan untuk membaca atau menulis nilai dalam JSON. Ini adalah kasus penggunaan untuk glz::hide
.
glz::hide
menyembunyikan nilai dari keluaran JSON sambil tetap mengizinkan akses API (dan penunjuk JSON).
struct hide_struct {
int i = 287 ;
double d = 3.14 ;
std::string hello = " Hello World " ;
};
template <>
struct glz ::meta<hide_struct> {
using T = hide_struct;
static constexpr auto value = object(&T::i, //
&T::d, //
" hello " , hide{&T::hello});
};
hide_struct s{};
auto b = glz::write_json(s);
expect (b == R"( {"i":287,"d":3.14} )" ); // notice that "hello" is hidden from the output
Anda dapat mengurai nomor JSON yang dikutip secara langsung ke tipe seperti double
, int
, dll. dengan memanfaatkan pembungkus glz::quoted
.
struct A {
double x;
std::vector< uint32_t > y;
};
template <>
struct glz ::meta<A> {
static constexpr auto value = object( " x " , glz::quoted_num<&A::x>, " y " , glz::quoted_num<&A::y>;
};
{
"x" : " 3.14 " ,
"y" : [ " 1 " , " 2 " , " 3 " ]
}
Nomor JSON yang dikutip akan diuraikan langsung ke dalam double
dan std::vector<uint32_t>
. Fungsi glz::quoted
juga berfungsi untuk objek dan array bersarang.
Glaze mendukung JSON Lines (atau Newline Delimited JSON) untuk tipe seperti array (misalnya std::vector
dan std::tuple
).
std::vector<std::string> x = { " Hello " , " World " , " Ice " , " Cream " };
std::string s = glz::write_ndjson(x).value_or( " error " );
auto ec = glz::read_ndjson(x, s);
Lihat direktori ext
untuk ekstensi.
Glaze didistribusikan di bawah lisensi MIT dengan pengecualian untuk formulir yang disematkan:
--- Pengecualian opsional terhadap lisensi ---
Sebagai pengecualian, jika, sebagai hasil kompilasi kode sumber Anda, bagian dari Perangkat Lunak ini tertanam ke dalam bentuk objek kode sumber yang dapat dieksekusi oleh mesin, Anda dapat mendistribusikan kembali bagian yang tertanam tersebut dalam bentuk objek tersebut tanpa menyertakan hak cipta dan izin. pemberitahuan.