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