xtensor
Loading...
Searching...
No Matches
xexpression_holder.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_XEXPRESSION_HOLDER_HPP
11#define XTENSOR_XEXPRESSION_HOLDER_HPP
12
13#include <memory>
14
15#include <nlohmann/json.hpp>
16
17#include "xarray.hpp"
18#include "xjson.hpp"
19#include "xtensor_config.hpp"
20#include "xtl/xany.hpp"
21
22namespace xt
23{
24
25 namespace detail
26 {
27 class xexpression_holder_impl;
28
29 template <class CTE>
30 class xexpression_wrapper;
31 }
32
33 class xexpression_holder // Value semantic
34 {
35 public:
36
37 using implementation_type = detail::xexpression_holder_impl;
38
39 xexpression_holder() = default;
40
41 template <class E>
43
44 xexpression_holder(implementation_type* holder);
47
48 xexpression_holder& operator=(const xexpression_holder&);
50
51 void swap(xexpression_holder&);
52
53 void to_json(nlohmann::json&) const;
54 void from_json(const nlohmann::json&);
55
56 private:
57
58 void init_pointer_from_json(const nlohmann::json&);
59 void check_holder() const;
60
61 std::unique_ptr<implementation_type> p_holder;
62 };
63
64 /*************************************
65 * to_json and from_json declaration *
66 *************************************/
67
69 void to_json(nlohmann::json& j, const xexpression_holder& o);
70 void from_json(const nlohmann::json& j, xexpression_holder& o);
71
73
74 namespace detail
75 {
76 class xexpression_holder_impl // Entity semantic
77 {
78 public:
79
80 xexpression_holder_impl(xexpression_holder_impl&&) = delete;
81
82 xexpression_holder_impl& operator=(const xexpression_holder_impl&) = delete;
83 xexpression_holder_impl& operator=(xexpression_holder_impl&&) = delete;
84
85 virtual xexpression_holder_impl* clone() const = 0;
86 virtual void to_json(nlohmann::json&) const = 0;
87 virtual void from_json(const nlohmann::json&) = 0;
88 virtual ~xexpression_holder_impl() = default;
89
90 protected:
91
92 xexpression_holder_impl() = default;
93 xexpression_holder_impl(const xexpression_holder_impl&) = default;
94 };
95
96 template <class CTE>
97 class xexpression_wrapper : public xexpression_holder_impl
98 {
99 public:
100
101 template <class E>
102 xexpression_wrapper(E&& expr);
103
104 xexpression_wrapper* clone() const;
105
106 void to_json(nlohmann::json&) const;
107 void from_json(const nlohmann::json&);
108
109 ~xexpression_wrapper() = default;
110
111 protected:
112
113 xexpression_wrapper(const xexpression_wrapper&);
114
115 private:
116
117 CTE m_expression;
118 };
119 }
120
121 template <class E>
122 inline xexpression_holder::xexpression_holder(E&& expr)
123 : p_holder(new detail::xexpression_wrapper<E>(std::forward<E>(expr)))
124 {
125 }
126
127 inline xexpression_holder::xexpression_holder(implementation_type* holder)
128 : p_holder(holder)
129 {
130 }
131
132 inline xexpression_holder::xexpression_holder(const xexpression_holder& holder)
133 : p_holder(holder.p_holder->clone())
134 {
135 }
136
137 inline xexpression_holder::xexpression_holder(xexpression_holder&& holder)
138 : p_holder(std::move(holder.p_holder))
139 {
140 }
141
142 inline xexpression_holder& xexpression_holder::operator=(const xexpression_holder& holder)
143 {
144 xexpression_holder tmp(holder);
145 swap(tmp);
146 return *this;
147 }
148
149 inline xexpression_holder& xexpression_holder::operator=(xexpression_holder&& holder)
150 {
151 swap(holder);
152 return *this;
153 }
154
155 inline void xexpression_holder::swap(xexpression_holder& holder)
156 {
157 std::swap(p_holder, holder.p_holder);
158 }
159
160 inline void xexpression_holder::to_json(nlohmann::json& j) const
161 {
162 if (p_holder == nullptr)
163 {
164 return;
165 }
166 p_holder->to_json(j);
167 }
168
169 inline void xexpression_holder::from_json(const nlohmann::json& j)
170 {
171 if (!j.is_array())
172 {
173 XTENSOR_THROW(std::runtime_error, "Received a JSON that does not contain a tensor");
174 }
175
176 if (p_holder == nullptr)
177 {
178 init_pointer_from_json(j);
179 }
180 p_holder->from_json(j);
181 }
182
183 inline void xexpression_holder::init_pointer_from_json(const nlohmann::json& j)
184 {
185 if (j.is_array())
186 {
187 return init_pointer_from_json(j[0]);
188 }
189
190 if (j.is_number())
191 {
192 xt::xarray<double> empty_arr;
193 p_holder.reset(new detail::xexpression_wrapper<xt::xarray<double>>(std::move(empty_arr)));
194 }
195
196 if (j.is_boolean())
197 {
198 xt::xarray<bool> empty_arr;
199 p_holder.reset(new detail::xexpression_wrapper<xt::xarray<bool>>(std::move(empty_arr)));
200 }
201
202 if (j.is_string())
203 {
204 xt::xarray<std::string> empty_arr;
205 p_holder.reset(new detail::xexpression_wrapper<xt::xarray<std::string>>(std::move(empty_arr)));
206 }
207
208 XTENSOR_THROW(std::runtime_error, "Received a JSON with a tensor that contains unsupported data type");
209 }
210
211 inline void xexpression_holder::check_holder() const
212 {
213 if (p_holder == nullptr)
214 {
215 XTENSOR_THROW(std::runtime_error, "The holder does not contain an expression");
216 }
217 }
218
219 /****************************************
220 * to_json and from_json implementation *
221 ****************************************/
222
224 inline void to_json(nlohmann::json& j, const xexpression_holder& o)
225 {
226 o.to_json(j);
227 }
228
229 inline void from_json(const nlohmann::json& j, xexpression_holder& o)
230 {
231 o.from_json(j);
232 }
233
235
236 namespace detail
237 {
238 template <class CTE>
239 template <class E>
240 inline xexpression_wrapper<CTE>::xexpression_wrapper(E&& expr)
241 : xexpression_holder_impl()
242 , m_expression(std::forward<E>(expr))
243 {
244 }
245
246 template <class CTE>
247 inline xexpression_wrapper<CTE>* xexpression_wrapper<CTE>::clone() const
248 {
249 return new xexpression_wrapper<CTE>(*this);
250 }
251
252 template <class CTE>
253 inline void xexpression_wrapper<CTE>::to_json(nlohmann::json& j) const
254 {
255 ::xt::to_json(j, m_expression);
256 }
257
258 template <class CTE>
259 inline void xexpression_wrapper<CTE>::from_json(const nlohmann::json& j)
260 {
261 ::xt::from_json(j, m_expression);
262 }
263
264 template <class CTE>
265 inline xexpression_wrapper<CTE>::xexpression_wrapper(const xexpression_wrapper& wrapper)
266 : xexpression_holder_impl()
267 , m_expression(wrapper.m_expression)
268 {
269 }
270 }
271}
272
273#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
enable_xexpression< E > to_json(nlohmann::basic_json< M > &, const E &)
JSON serialization of an xtensor expression.
Definition xjson.hpp:133