Skip to content

Commit

Permalink
Separate container concepts #319 (#327)
Browse files Browse the repository at this point in the history
* add cmake preset file for simpler build+test

* save unchanged common.hpp - clang-format changes

* attempt to separate write from read of mapt_t

* use result of [[nodiscard]] function in test; avoid warning

* gracefully fail testing variant to avoid subproc aborted

* fix variant auto-deducible func w/ split maps

* rm 'value_type' nested type alias requirement for ranges

* refactor to_json(map) for in ranges + first el mistreatment

* require 'range' concept to be input range

* use free functions that are compat. w/ more types

* create some tests for writing map-like ranges

* add basic writing in input ranges as arrays

* replace ranges::empty() w/ internal alternative for older compilers

* disable tests w/ views when views unavailable

* fix circular include

* fix MSVC literal issue

* use glz::sv instead of literal sv

* attempt MSVC fix removing operator""

* serialize pair as object

* correct expected json in write pair test

* provide reading specialization for pair

* uncomment "issue". UT can run, there's just no default printing for maps

* test reading pairs

* read binary pair specialization

* refactor json tests to avoid expected. glz::expected subset of std::expected

* provide deduction guides on test-case structs for apple-clang

* classify pair_t as object when auto-deducing variant

* document breaking std::pair change

* Version 1.3.0 bump

---------

Co-authored-by: Stephen Berry <stephenberry.developer@gmail.com>
  • Loading branch information
justend29 and stephenberry committed Jul 2, 2023
1 parent 25e16c7 commit 1589d3c
Show file tree
Hide file tree
Showing 16 changed files with 476 additions and 166 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
*build/
*build-*/
*bin/
.idea/
.vscode/
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ include(cmake/prelude.cmake)

project(
glaze
VERSION 1.2.6
VERSION 1.3.0
LANGUAGES CXX
)

Expand Down
45 changes: 45 additions & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"version": 3,
"cmakeMinimumRequired": {
"major": 3,
"minor": 23,
"patch": 0
},
"configurePresets": [
{
"name": "dev",
"displayName": "Developer Mode",
"description": "Builds Glaze w/ tests and downloaded test dependencies",
"binaryDir": "${sourceDir}/build",
"generator": "Ninja",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"glaze_DEVELOPER_MODE": true,
"BUILD_TESTING": true
}
},
{
"name": "release",
"displayName": "Release",
"description": "Optimized library build of exclusively library",
"binaryDir": "${sourceDir}/build-release",
"generator": "Ninja",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"glaze_DEVELOPER_MODE": false,
"BUILD_TESTING": false
}
}
],
"testPresets": [
{
"name": "all",
"displayName": "Automated Tests",
"configurePreset": "dev",
"output": {
"verbosity": "verbose",
"outputOnFailure": true
}
}
]
}
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Glaze
One of the fastest JSON libraries in the world. Glaze reads and writes from C++ memory, simplifying interfaces and offering incredible performance.

> BREAKING v1.3.0 CHANGE: `std::pair` is now handled as a JSON object (`{"first":second}`}. If you require a JSON array of two items, use `std::array` or `std::tuple`.
## Highlights

Glaze requires C++20, using concepts for cleaner code and more helpful errors.
Expand Down Expand Up @@ -728,4 +730,4 @@ See the `ext` directory for extensions.
# License
Glaze is distributed under the MIT license.
Glaze is distributed under the MIT license.eee
44 changes: 42 additions & 2 deletions include/glaze/binary/read.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ namespace glz
template <auto Opts>
GLZ_ALWAYS_INLINE static void op(auto&& value, is_context auto&& ctx, auto&& it, auto&& end) noexcept
{
using V = typename std::decay_t<T>::value_type;
using V = range_value_t<std::decay_t<T>>;

const auto tag = uint8_t(*it);

Expand Down Expand Up @@ -320,7 +320,47 @@ namespace glz
}
};

template <map_t T>
template <pair_t T>
struct from_binary<T> final
{
template <auto Opts>
GLZ_ALWAYS_INLINE static void op(T& value, is_context auto&& ctx, auto&& it, auto&& end) noexcept
{
const auto tag = uint8_t(*it);
if (get_bits<3>(tag) != tag::object) {
ctx.error = error_code::syntax_error;
return;
}

using Key = typename T::first_type;
if constexpr (str_t<Key>) {
if (get_bits<3, 2>(tag) != 0) {
ctx.error = error_code::syntax_error;
return;
}
}
else {
static constexpr uint8_t type_id = 1 + std::unsigned_integral<Key>;
if (get_bits<3, 2>(tag) != type_id) {
ctx.error = error_code::syntax_error;
return;
}
}

++it;

const auto n = int_from_compressed(it, end);
if (n != 1) {
ctx.error = error_code::syntax_error;
return;
}

read<binary>::op<Opts>(value.first, ctx, it, end);
read<binary>::op<Opts>(value.second, ctx, it, end);
}
};

template <readable_map_t T>
struct from_binary<T> final
{
template <auto Opts>
Expand Down
32 changes: 28 additions & 4 deletions include/glaze/binary/write.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ namespace glz
template <auto Opts, class... Args>
GLZ_ALWAYS_INLINE static void op(auto&& value, is_context auto&& ctx, Args&&... args) noexcept
{
using V = typename std::decay_t<T>::value_type;
using V = range_value_t<std::decay_t<T>>;

uint8_t tag;

Expand Down Expand Up @@ -326,7 +326,31 @@ namespace glz
}
};

template <map_t T>
template <pair_t T>
struct to_binary<T> final
{
template <auto Opts, class... Args>
GLZ_ALWAYS_INLINE static auto op(auto&& value, is_context auto&& ctx, Args&&... args) noexcept
{
using Key = typename T::first_type;

uint8_t tag = tag::object;
if constexpr (str_t<Key>) {
// set_bits<3, 1, uint8_t>(tag, 0); // no need to set zero
}
else {
set_bits<3, 2, uint8_t>(tag, 1 + std::unsigned_integral<Key>);
}
dump_type(tag, args...);

dump_int<Opts>(1, args...);
const auto& [k, v] = value;
write<binary>::op<Opts>(k, ctx, args...);
write<binary>::op<Opts>(v, ctx, args...);
}
};

template <writable_map_t T>
struct to_binary<T> final
{
template <auto Opts, class... Args>
Expand Down Expand Up @@ -457,7 +481,7 @@ namespace glz
detail::write<binary>::op<Opts>(value, ctx, buffer);
}
else {
static_assert(detail::glaze_object_t<std::decay_t<T>> || detail::map_t<std::decay_t<T>>,
static_assert(detail::glaze_object_t<std::decay_t<T>> || detail::writable_map_t<std::decay_t<T>>,
"Only object types are supported for partial.");
static constexpr auto sorted = sort_json_ptrs(partial);
static constexpr auto groups = glz::group_json_ptrs<sorted>();
Expand Down Expand Up @@ -490,7 +514,7 @@ namespace glz
std::ignore = write<sub_partial, Opts>(glz::detail::get_member(value, member_ptr), buffer, ctx);
});
}
else if constexpr (detail::map_t<std::decay_t<T>>) {
else if constexpr (detail::writable_map_t<std::decay_t<T>>) {
glz::for_each<N>([&](auto I) {
using index_t = decltype(I);
using group_t = std::tuple_element_t<I, decltype(groups)>;
Expand Down
Loading

0 comments on commit 1589d3c

Please sign in to comment.