xtensor
Loading...
Searching...
No Matches
xjson.hpp
1/***************************************************************************
2 * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
3 * Copyright (c) QuantStack *
4 * *
5 * Distributed under the terms of the BSD 3-Clause License. *
6 * *
7 * The full license is in the file LICENSE, distributed with this software. *
8 ****************************************************************************/
9
10#ifndef XTENSOR_JSON_HPP
11#define XTENSOR_JSON_HPP
12
13#include <cstddef>
14#include <stdexcept>
15#include <utility>
16
17#include <nlohmann/json.hpp>
18
19#include "xstrided_view.hpp"
20#include "xtensor_config.hpp"
21
22namespace xt
23{
24 /*************************************
25 * to_json and from_json declaration *
26 *************************************/
27
28 template <template <typename U, typename V, typename... Args> class M, class E>
29 enable_xexpression<E> to_json(nlohmann::basic_json<M>&, const E&);
30
31 template <template <typename U, typename V, typename... Args> class M, class E>
32 enable_xcontainer_semantics<E> from_json(const nlohmann::basic_json<M>&, E&);
33
35 template <template <typename U, typename V, typename... Args> class M, class E>
36 enable_xview_semantics<E> from_json(const nlohmann::basic_json<M>&, E&);
37
39
40 /****************************************
41 * to_json and from_json implementation *
42 ****************************************/
43
44 namespace detail
45 {
46 template <template <typename U, typename V, typename... Args> class M, class D>
47 void to_json_impl(nlohmann::basic_json<M>& j, const xexpression<D>& e, xstrided_slice_vector& slices)
48 {
49 const auto view = strided_view(e.derived_cast(), slices);
50 if (view.dimension() == 0)
51 {
52 j = view();
53 }
54 else
55 {
56 j = nlohmann::basic_json<M>::array();
57 using size_type = typename D::size_type;
58 size_type nrows = view.shape()[0];
59 for (size_type i = 0; i != nrows; ++i)
60 {
61 slices.push_back(i);
62 nlohmann::basic_json<M> k;
63 to_json_impl(k, e, slices);
64 j.push_back(std::move(k));
65 slices.pop_back();
66 }
67 }
68 }
69
70 template <template <typename U, typename V, typename... Args> class M, class D>
71 inline void
72 from_json_impl(const nlohmann::basic_json<M>& j, xexpression<D>& e, xstrided_slice_vector& slices)
73 {
74 auto view = strided_view(e.derived_cast(), slices);
75
76 if (view.dimension() == 0)
77 {
78 view() = j.template get<std::remove_reference_t<decltype(view())>>();
79 }
80 else
81 {
82 using size_type = typename D::size_type;
83 size_type nrows = view.shape()[0];
84 for (size_type i = 0; i != nrows; ++i)
85 {
86 slices.push_back(i);
87 const nlohmann::basic_json<M>& k = j[i];
88 from_json_impl(k, e, slices);
89 slices.pop_back();
90 }
91 }
92 }
93
94 template <template <typename U, typename V, typename... Args> class M>
95 inline unsigned int json_dimension(const nlohmann::basic_json<M>& j)
96 {
97 if (j.is_array() && j.size())
98 {
99 return 1 + json_dimension(j[0]);
100 }
101 else
102 {
103 return 0;
104 }
105 }
106
107 template <template <typename U, typename V, typename... Args> class M, class S>
108 inline void json_shape(const nlohmann::basic_json<M>& j, S& s, std::size_t pos = 0)
109 {
110 if (j.is_array())
111 {
112 auto size = j.size();
113 s[pos] = size;
114 if (size)
115 {
116 json_shape(j[0], s, pos + 1);
117 }
118 }
119 }
120 }
121
132 template <template <typename U, typename V, typename... Args> class M, class E>
133 inline enable_xexpression<E> to_json(nlohmann::basic_json<M>& j, const E& e)
134 {
135 auto sv = xstrided_slice_vector();
136 detail::to_json_impl(j, e, sv);
137 }
138
155 template <template <typename U, typename V, typename... Args> class M, class E>
156 inline enable_xcontainer_semantics<E> from_json(const nlohmann::basic_json<M>& j, E& e)
157 {
158 auto dimension = detail::json_dimension(j);
159 auto s = xtl::make_sequence<typename E::shape_type>(dimension);
160 detail::json_shape(j, s);
161
162 // In the case of a container, we resize the container.
163 e.resize(s);
164
165 auto sv = xstrided_slice_vector();
166 detail::from_json_impl(j, e, sv);
167 }
168
170 template <template <typename U, typename V, typename... Args> class M, class E>
171 inline enable_xview_semantics<E> from_json(const nlohmann::basic_json<M>& j, E& e)
172 {
173 typename E::shape_type s;
174 detail::json_shape(j, s);
175
176 // In the case of a view, we check the size of the container.
177 if (!std::equal(s.cbegin(), s.cend(), e.shape().cbegin()))
178 {
179 XTENSOR_THROW(std::runtime_error, "Shape mismatch when deserializing JSON to view");
180 }
181
182 auto sv = xstrided_slice_vector();
183 detail::from_json_impl(j, e, sv);
184 }
185
187}
188
189#endif
standard mathematical functions for xexpressions
enable_xcontainer_semantics< E > from_json(const nlohmann::basic_json< M > &, E &)
JSON deserialization of a xtensor expression with a container or a view semantics.
Definition xjson.hpp:156
std::vector< xstrided_slice< std::ptrdiff_t > > xstrided_slice_vector
vector of slices used to build a xstrided_view
enable_xexpression< E > to_json(nlohmann::basic_json< M > &, const E &)
JSON serialization of an xtensor expression.
Definition xjson.hpp:133
auto strided_view(E &&e, S &&shape, X &&stride, std::size_t offset=0, layout_type layout=L) noexcept
Construct a strided view from an xexpression, shape, strides and offset.
auto view(E &&e, S &&... slices)
Constructs and returns a view on the specified xexpression.
Definition xview.hpp:1834