1 //////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (C) 1996-2021 The Octave Project Developers 4 // 5 // See the file COPYRIGHT.md in the top-level directory of this 6 // distribution or <https://octave.org/copyright/>. 7 // 8 // This file is part of Octave. 9 // 10 // Octave is free software: you can redistribute it and/or modify it 11 // under the terms of the GNU General Public License as published by 12 // the Free Software Foundation, either version 3 of the License, or 13 // (at your option) any later version. 14 // 15 // Octave is distributed in the hope that it will be useful, but 16 // WITHOUT ANY WARRANTY; without even the implied warranty of 17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 // GNU General Public License for more details. 19 // 20 // You should have received a copy of the GNU General Public License 21 // along with Octave; see the file COPYING. If not, see 22 // <https://www.gnu.org/licenses/>. 23 // 24 //////////////////////////////////////////////////////////////////////// 25 26 #if ! defined (octave_pt_tm_const_h) 27 #define octave_pt_tm_const_h 1 28 29 #include "octave-config.h" 30 31 #include <list> 32 #include <memory> 33 #include <string> 34 35 #include "Array.h" 36 #include "Sparse.h" 37 38 #include "data.h" 39 #include "dim-vector.h" 40 #include "oct-map.h" 41 #include "ov.h" 42 #include "ovl.h" 43 #include "pt-arg-list.h" 44 #include "pt-mat.h" 45 46 namespace octave 47 { 48 class tree_evaluator; 49 50 // Evaluate tree_matrix objects and convert them to octave_value 51 // arrays (full and sparse numeric, char, cell, struct, class and 52 // anything else that works like an array). Use a separate class 53 // (tm_const) and pass the evaluator object to it instead of doing 54 // all this work in tree_evaluator::visit_matrix because the job is 55 // fairly large and requires extra data (stored in the tm_info 56 // class) for each row and for the overall array. 57 58 // Evaluate all elements of the array, recording info about each 59 // row, then create summary info for the full array. Compute the 60 // result type and dimension first before copying values. 61 62 // FIXME: Handle overloading of horzcat and vertcat for for built-in 63 // types. 64 65 // Summary info about the current row or matrix. 66 67 class tm_info 68 { 69 public: 70 tm_info(bool obj_is_empty)71 tm_info (bool obj_is_empty) 72 : m_dv (0, 0), m_all_strings (true), m_all_sq_strings (true), 73 m_all_dq_strings (true), m_some_strings (false), 74 m_all_real (true), m_all_complex (true), m_all_empty (true), 75 m_any_cell (false), m_any_sparse (false), 76 m_any_class (false), m_all_1x1 (! obj_is_empty), 77 m_first_elem_is_struct (false), m_class_name () 78 { } 79 dims(void)80 dim_vector dims (void) const { return m_dv; } 81 rows(void)82 octave_idx_type rows (void) const { return m_dv(0); } cols(void)83 octave_idx_type cols (void) const { return m_dv(1); } 84 all_strings_p(void)85 bool all_strings_p (void) const { return m_all_strings; } all_sq_strings_p(void)86 bool all_sq_strings_p (void) const { return m_all_sq_strings; } all_dq_strings_p(void)87 bool all_dq_strings_p (void) const { return m_all_dq_strings; } some_strings_p(void)88 bool some_strings_p (void) const { return m_some_strings; } all_real_p(void)89 bool all_real_p (void) const { return m_all_real; } all_complex_p(void)90 bool all_complex_p (void) const { return m_all_complex; } all_empty_p(void)91 bool all_empty_p (void) const { return m_all_empty; } any_cell_p(void)92 bool any_cell_p (void) const { return m_any_cell; } any_sparse_p(void)93 bool any_sparse_p (void) const { return m_any_sparse; } any_class_p(void)94 bool any_class_p (void) const { return m_any_class; } all_1x1_p(void)95 bool all_1x1_p (void) const { return m_all_1x1; } first_elem_struct_p(void)96 bool first_elem_struct_p (void) const { return m_first_elem_is_struct; } 97 class_name(void)98 std::string class_name (void) const { return m_class_name; } 99 100 protected: 101 102 // Size of this row or matrix after evaluation. 103 dim_vector m_dv; 104 105 // Are all elements character strings? 106 bool m_all_strings; 107 108 // Are all elements double-quoted character strings? 109 bool m_all_sq_strings; 110 111 // Are all elements single-quoted character strings? 112 bool m_all_dq_strings; 113 114 // Are any elements character strings? 115 bool m_some_strings; 116 117 // Are all elements real valued? 118 bool m_all_real; 119 120 // Are all elements complex valued? 121 bool m_all_complex; 122 123 // Are all elements empty? 124 bool m_all_empty; 125 126 // Are any elements cells? 127 bool m_any_cell; 128 129 // Are any elements sparse arrays? 130 bool m_any_sparse; 131 132 // Are any elements sparse class objects? 133 bool m_any_class; 134 135 // Do all elements have dimensions 1x1? 136 bool m_all_1x1; 137 138 // Is the first element a struct? 139 bool m_first_elem_is_struct; 140 141 // Class name of result. 142 std::string m_class_name; 143 }; 144 145 class tm_row_const : public tm_info 146 { 147 public: 148 149 typedef std::list<octave_value>::iterator iterator; 150 typedef std::list<octave_value>::const_iterator const_iterator; 151 152 tm_row_const (void) = delete; 153 tm_row_const(const tree_argument_list & row,tree_evaluator & tw)154 tm_row_const (const tree_argument_list& row, tree_evaluator& tw) 155 : tm_info (row.empty ()), m_values () 156 { 157 init (row, tw); 158 } 159 160 tm_row_const (const tm_row_const&) = default; 161 162 tm_row_const& operator = (const tm_row_const&) = delete; 163 164 ~tm_row_const (void) = default; 165 begin(void)166 iterator begin (void) { return m_values.begin (); } begin(void)167 const_iterator begin (void) const { return m_values.begin (); } 168 end(void)169 iterator end (void) { return m_values.end (); } end(void)170 const_iterator end (void) const { return m_values.end (); } 171 empty(void)172 bool empty (void) const { return m_values.empty (); } 173 length(void)174 std::size_t length (void) const { return m_values.size (); } 175 176 void cellify (void); 177 178 private: 179 180 std::list<octave_value> m_values; 181 182 void init_element (const octave_value&, bool&); 183 184 void init (const tree_argument_list&, tree_evaluator& tw); 185 }; 186 187 class tm_const : public tm_info 188 { 189 public: 190 191 typedef std::list<tm_row_const>::iterator iterator; 192 typedef std::list<tm_row_const>::const_iterator const_iterator; 193 194 tm_const (void) = delete; 195 tm_const(const tree_matrix & tm,tree_evaluator & tw)196 tm_const (const tree_matrix& tm, tree_evaluator& tw) 197 : tm_info (tm.empty ()), m_evaluator (tw), m_tm_rows () 198 { 199 init (tm); 200 } 201 202 // No copying! 203 204 tm_const (const tm_const&) = delete; 205 206 tm_const& operator = (const tm_const&) = delete; 207 208 ~tm_const (void) = default; 209 210 octave_value concat (char string_fill_char) const; 211 212 private: 213 214 tree_evaluator& m_evaluator; 215 216 // The list of lists of octave_value objects that contain the 217 // values of elements in each row of the tree_matrix object we are 218 // evaluating. 219 220 std::list<tm_row_const> m_tm_rows; 221 222 void init (const tree_matrix& tm); 223 224 octave_value char_array_concat (char string_fill_char) const; 225 226 octave_value class_concat (void) const; 227 228 octave_value generic_concat (void) const; 229 230 template <typename TYPE> 231 void array_concat_internal (TYPE& result) const; 232 233 template <typename TYPE> 234 TYPE array_concat (void) const; 235 236 template <typename TYPE> 237 TYPE sparse_array_concat (void) const; 238 239 template <typename MAP> 240 octave_map map_concat (void) const; 241 }; 242 } 243 244 #endif 245