|
17 | 17 | * along with xeus-octave. If not, see <http://www.gnu.org/licenses/>. |
18 | 18 | */ |
19 | 19 |
|
20 | | -#ifndef XEUS_OCTAVE_UTILS_HPP |
21 | | -#define XEUS_OCTAVE_UTILS_HPP |
| 20 | +#ifndef XEUS_OCTAVE_UTILS_H |
| 21 | +#define XEUS_OCTAVE_UTILS_H |
22 | 22 |
|
| 23 | +#include <octave/dim-vector.h> |
| 24 | +#include <octave/graphics-handle.h> |
| 25 | +#include <octave/graphics.h> |
| 26 | +#include <octave/int8NDArray.h> |
23 | 27 | #include <octave/interpreter.h> |
24 | 28 | #include <octave/ov-builtin.h> |
| 29 | +#include <octave/ov-classdef.h> |
25 | 30 | #include <octave/ov-fcn-handle.h> |
26 | 31 | #include <octave/ov-null-mat.h> |
27 | 32 | #include <octave/ov.h> |
|
30 | 35 |
|
31 | 36 | #include <xeus/xguid.hpp> |
32 | 37 | #include <xtl/xoptional.hpp> |
| 38 | +#include <xwidgets/xholder.hpp> |
| 39 | +#include <xwidgets/ximage.hpp> |
| 40 | + |
| 41 | +#include "xeus-octave/plotstream.hpp" |
33 | 42 |
|
34 | 43 | namespace xeus_octave::utils |
35 | 44 | { |
36 | 45 |
|
| 46 | +/** |
| 47 | + * Convert octave_value to any generic type. Fails at runtime if not implemented in |
| 48 | + * octave default conversions |
| 49 | + */ |
| 50 | +template <class T> inline void from_ov(octave_value const&, T&, octave::interpreter&) |
| 51 | +{ |
| 52 | + static_assert(!sizeof(T*), "Please implement a proper conversion function"); |
| 53 | +} |
| 54 | + |
| 55 | +/** |
| 56 | + * Convert octave_value to int |
| 57 | + */ |
| 58 | +inline void from_ov(octave_value const& from, int& to, octave::interpreter&) |
| 59 | +{ |
| 60 | + to = from.int_value(); |
| 61 | +} |
| 62 | + |
| 63 | +/** |
| 64 | + * Convert octave_value to bool |
| 65 | + */ |
| 66 | +inline void from_ov(octave_value const& from, bool& to, octave::interpreter&) |
| 67 | +{ |
| 68 | + to = from.bool_value(); |
| 69 | +} |
| 70 | + |
| 71 | +/** |
| 72 | + * Convert octave_value to std::string |
| 73 | + */ |
| 74 | +inline void from_ov(octave_value const& from, std::string& to, octave::interpreter&) |
| 75 | +{ |
| 76 | + to = from.string_value(); |
| 77 | +} |
| 78 | + |
| 79 | +/** |
| 80 | + * Convert octave_value to double |
| 81 | + */ |
| 82 | +inline void from_ov(octave_value const& from, double& to, octave::interpreter&) |
| 83 | +{ |
| 84 | + to = from.scalar_value(); |
| 85 | +} |
| 86 | + |
| 87 | +/** |
| 88 | + * Convert octave_value to xguid. |
| 89 | + * Used for xwidgets |
| 90 | + */ |
| 91 | +inline void from_ov(octave_value const& from, xeus::xguid& to, octave::interpreter& interpreter) |
| 92 | +{ |
| 93 | + std::string _to; |
| 94 | + from_ov(from, _to, interpreter); |
| 95 | + to = xeus::xguid(_to); |
| 96 | +} |
| 97 | + |
| 98 | +/** |
| 99 | + * Convert octave_value to widget (holder) |
| 100 | + */ |
| 101 | +inline void from_ov(octave_value const& from, xw::xholder& to, octave::interpreter& interpreter) |
| 102 | +{ |
| 103 | + // This is an xwidget |
| 104 | + if (from.is_classdef_object()) |
| 105 | + { |
| 106 | + octave_classdef* cls = from.classdef_object_value(); |
| 107 | + octave_value_list ret = cls->subsref(".", {ovl("id")}, 1); |
| 108 | + xeus::xguid id; |
| 109 | + |
| 110 | + from_ov(ret(0), id, interpreter); |
| 111 | + to = xw::make_id_holder(id); |
| 112 | + } |
| 113 | +} |
| 114 | + |
| 115 | +/** |
| 116 | + * Convert octave value to a generic vector |
| 117 | + */ |
| 118 | +template <class T> inline void from_ov(octave_value const& from, std::vector<T>& to, octave::interpreter& interpreter) |
| 119 | +{ |
| 120 | + Cell cell = from.cell_value(); |
| 121 | + |
| 122 | + for (int i = 0; i < cell.numel(); i++) |
| 123 | + { |
| 124 | + T element; |
| 125 | + from_ov(cell(0, i), element, interpreter); |
| 126 | + to.push_back(element); |
| 127 | + } |
| 128 | +} |
| 129 | + |
| 130 | +/** |
| 131 | + * Convert octave_value to a vector of chars (i.e. byte array) |
| 132 | + */ |
| 133 | +inline void from_ov(octave_value const& from, std::vector<char>& to, octave::interpreter&) |
| 134 | +{ |
| 135 | + if (from.is_string()) |
| 136 | + { |
| 137 | + std::string _to = from.string_value(); |
| 138 | + std::copy(_to.begin(), _to.end(), std::back_inserter(to)); |
| 139 | + } |
| 140 | + else |
| 141 | + { |
| 142 | + auto array = from.uint8_array_value(); |
| 143 | + for (int i = 0; i < array.numel(); i++) |
| 144 | + to.push_back(array.xelem(i).char_value()); |
| 145 | + } |
| 146 | +} |
| 147 | + |
| 148 | +/** |
| 149 | + * Convert octave_value to a xtl::xoptional generic value |
| 150 | + */ |
| 151 | +template <class T> |
| 152 | +inline void from_ov(octave_value const& from, xtl::xoptional<T>& to, octave::interpreter& interpreter) |
| 153 | +{ |
| 154 | + if (!from.isnull()) |
| 155 | + { |
| 156 | + T _to; |
| 157 | + from_ov(from, _to, interpreter); |
| 158 | + to = _to; |
| 159 | + } |
| 160 | + else |
| 161 | + to = xtl::xoptional<T>(); |
| 162 | +} |
| 163 | + |
| 164 | +/** |
| 165 | + * Convert generic type to octave_value |
| 166 | + */ |
| 167 | +template <class T> inline void to_ov(octave_value& to, T const& from, octave::interpreter&) |
| 168 | +{ |
| 169 | + to = octave_value(from); |
| 170 | +} |
| 171 | + |
| 172 | +/** |
| 173 | + * Convert widget to octave_value. |
| 174 | + * Simply returns string containing id |
| 175 | + */ |
| 176 | +inline void to_ov(octave_value& to, xw::xholder const& from, octave::interpreter&) |
| 177 | +{ |
| 178 | + to = octave_value(from.id().c_str()); |
| 179 | +} |
| 180 | + |
| 181 | +/** |
| 182 | + * Convert a generic std::vector to octave_value (cell array) |
| 183 | + */ |
| 184 | +template <class T> inline void to_ov(octave_value& to, std::vector<T> const& from, octave::interpreter& interpreter) |
| 185 | +{ |
| 186 | + Cell a; |
| 187 | + octave_idx_type i = 0; |
| 188 | + |
| 189 | + a.resize(dim_vector(static_cast<octave_idx_type>(from.size()), 1)); |
| 190 | + |
| 191 | + for (auto e : from) |
| 192 | + to_ov(a.elem(i++, 0), e, interpreter); |
| 193 | + |
| 194 | + to = a; |
| 195 | +} |
| 196 | + |
| 197 | +/** |
| 198 | + * Convert a vector of char (i.e. bytearray) to octave_value (uint8 matrix) |
| 199 | + */ |
| 200 | +inline void to_ov(octave_value& to, std::vector<char> const& from, octave::interpreter&) |
| 201 | +{ |
| 202 | + auto dv = dim_vector(1, static_cast<octave_idx_type>(from.size())); |
| 203 | + uint8NDArray _to(Array<char>(from, dv)); |
| 204 | + to = _to; |
| 205 | +} |
| 206 | + |
| 207 | +/** |
| 208 | + * Convert a generic xtl::xoptional to octave_value (value or null matrix) |
| 209 | + */ |
| 210 | +template <class T> inline void to_ov(octave_value& to, xtl::xoptional<T> const& from, octave::interpreter& interpreter) |
| 211 | +{ |
| 212 | + if (from.has_value()) |
| 213 | + to_ov(to, from.value(), interpreter); |
| 214 | + else |
| 215 | + to = octave_null_matrix::instance; |
| 216 | +} |
| 217 | + |
| 218 | +/** |
| 219 | + * Convert a xguid to octave_value (sq_string) |
| 220 | + */ |
| 221 | +inline void to_ov(octave_value& to, xeus::xguid const& from, octave::interpreter& interpreter) |
| 222 | +{ |
| 223 | + to_ov(to, std::string(from), interpreter); |
| 224 | +} |
| 225 | + |
| 226 | +template <typename M> inline octave_value make_fcn_handle(M ff, std::string const& nm) |
| 227 | +{ |
| 228 | + octave_value fcn(new octave_builtin(ff, nm)); |
| 229 | + return octave_value(new octave_fcn_handle(fcn)); |
| 230 | +} |
| 231 | + |
37 | 232 | inline void add_native_binding(octave::interpreter& interpreter, std::string const& name, octave_builtin::fcn ff) |
38 | 233 | { |
39 | 234 | octave_builtin* fcn = new octave_builtin(ff, name, __FILE__, ""); |
|
0 commit comments