1 // SPDX-License-Identifier: Apache-2.0 2 // 3 // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) 4 // Copyright 2008-2016 National ICT Australia (NICTA) 5 // 6 // Licensed under the Apache License, Version 2.0 (the "License"); 7 // you may not use this file except in compliance with the License. 8 // You may obtain a copy of the License at 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 // ------------------------------------------------------------------------ 17 18 19 //! \addtogroup field 20 //! @{ 21 22 23 24 struct field_prealloc_n_elem 25 { 26 static constexpr uword val = 16; 27 }; 28 29 30 31 //! A lightweight 1D/2D/3D container for arbitrary objects 32 //! (the objects must have a copy constructor) 33 34 template<typename oT> 35 class field 36 { 37 public: 38 39 typedef oT object_type; 40 41 const uword n_rows; //!< number of rows (read-only) 42 const uword n_cols; //!< number of columns (read-only) 43 const uword n_slices; //!< number of slices (read-only) 44 const uword n_elem; //!< number of elements (read-only) 45 46 47 private: 48 49 arma_aligned oT** mem; //!< pointers to stored objects 50 arma_aligned oT* mem_local[ field_prealloc_n_elem::val ]; //!< local storage, for small fields 51 52 53 public: 54 55 inline ~field(); 56 inline field(); 57 58 inline field(const field& x); 59 inline field& operator=(const field& x); 60 61 inline field(const subview_field<oT>& x); 62 inline field& operator=(const subview_field<oT>& x); 63 64 inline explicit field(const uword n_elem_in); 65 inline explicit field(const uword n_rows_in, const uword n_cols_in); 66 inline explicit field(const uword n_rows_in, const uword n_cols_in, const uword n_slices_in); 67 inline explicit field(const SizeMat& s); 68 inline explicit field(const SizeCube& s); 69 70 inline void set_size(const uword n_obj_in); 71 inline void set_size(const uword n_rows_in, const uword n_cols_in); 72 inline void set_size(const uword n_rows_in, const uword n_cols_in, const uword n_slices_in); 73 inline void set_size(const SizeMat& s); 74 inline void set_size(const SizeCube& s); 75 76 inline field(const std::vector<oT>& x); 77 inline field& operator=(const std::vector<oT>& x); 78 79 inline field(const std::initializer_list<oT>& list); 80 inline field& operator=(const std::initializer_list<oT>& list); 81 82 inline field(const std::initializer_list< std::initializer_list<oT> >& list); 83 inline field& operator=(const std::initializer_list< std::initializer_list<oT> >& list); 84 85 inline field(field&& X); 86 inline field& operator=(field&& X); 87 88 template<typename oT2> 89 inline void copy_size(const field<oT2>& x); 90 91 arma_inline arma_warn_unused oT& operator[](const uword i); 92 arma_inline arma_warn_unused const oT& operator[](const uword i) const; 93 94 arma_inline arma_warn_unused oT& at(const uword i); 95 arma_inline arma_warn_unused const oT& at(const uword i) const; 96 97 arma_inline arma_warn_unused oT& operator()(const uword i); 98 arma_inline arma_warn_unused const oT& operator()(const uword i) const; 99 100 arma_inline arma_warn_unused oT& at(const uword row, const uword col); 101 arma_inline arma_warn_unused const oT& at(const uword row, const uword col) const; 102 103 arma_inline arma_warn_unused oT& at(const uword row, const uword col, const uword slice); 104 arma_inline arma_warn_unused const oT& at(const uword row, const uword col, const uword slice) const; 105 106 arma_inline arma_warn_unused oT& operator()(const uword row, const uword col); 107 arma_inline arma_warn_unused const oT& operator()(const uword row, const uword col) const; 108 109 arma_inline arma_warn_unused oT& operator()(const uword row, const uword col, const uword slice); 110 arma_inline arma_warn_unused const oT& operator()(const uword row, const uword col, const uword slice) const; 111 112 113 arma_inline arma_warn_unused oT& front(); 114 arma_inline arma_warn_unused const oT& front() const; 115 116 arma_inline arma_warn_unused oT& back(); 117 arma_inline arma_warn_unused const oT& back() const; 118 119 120 arma_cold inline field_injector<field> operator<<(const oT& val); 121 arma_cold inline field_injector<field> operator<<(const injector_end_of_row<>& x); 122 123 124 inline subview_field<oT> row(const uword row_num); 125 inline const subview_field<oT> row(const uword row_num) const; 126 127 inline subview_field<oT> col(const uword col_num); 128 inline const subview_field<oT> col(const uword col_num) const; 129 130 inline subview_field<oT> slice(const uword slice_num); 131 inline const subview_field<oT> slice(const uword slice_num) const; 132 133 inline subview_field<oT> rows(const uword in_row1, const uword in_row2); 134 inline const subview_field<oT> rows(const uword in_row1, const uword in_row2) const; 135 136 inline subview_field<oT> cols(const uword in_col1, const uword in_col2); 137 inline const subview_field<oT> cols(const uword in_col1, const uword in_col2) const; 138 139 inline subview_field<oT> slices(const uword in_slice1, const uword in_slice2); 140 inline const subview_field<oT> slices(const uword in_slice1, const uword in_slice2) const; 141 142 inline subview_field<oT> subfield(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2); 143 inline const subview_field<oT> subfield(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const; 144 145 inline subview_field<oT> subfield(const uword in_row1, const uword in_col1, const uword in_slice1, const uword in_row2, const uword in_col2, const uword in_slice2); 146 inline const subview_field<oT> subfield(const uword in_row1, const uword in_col1, const uword in_slice1, const uword in_row2, const uword in_col2, const uword in_slice2) const; 147 148 inline subview_field<oT> subfield(const uword in_row1, const uword in_col1, const SizeMat& s); 149 inline const subview_field<oT> subfield(const uword in_row1, const uword in_col1, const SizeMat& s) const; 150 151 inline subview_field<oT> subfield(const uword in_row1, const uword in_col1, const uword in_slice1, const SizeCube& s); 152 inline const subview_field<oT> subfield(const uword in_row1, const uword in_col1, const uword in_slice1, const SizeCube& s) const; 153 154 inline subview_field<oT> subfield(const span& row_span, const span& col_span); 155 inline const subview_field<oT> subfield(const span& row_span, const span& col_span) const; 156 157 inline subview_field<oT> subfield(const span& row_span, const span& col_span, const span& slice_span); 158 inline const subview_field<oT> subfield(const span& row_span, const span& col_span, const span& slice_span) const; 159 160 inline subview_field<oT> operator()(const span& row_span, const span& col_span); 161 inline const subview_field<oT> operator()(const span& row_span, const span& col_span) const; 162 163 inline subview_field<oT> operator()(const span& row_span, const span& col_span, const span& slice_span); 164 inline const subview_field<oT> operator()(const span& row_span, const span& col_span, const span& slice_span) const; 165 166 inline subview_field<oT> operator()(const uword in_row1, const uword in_col1, const SizeMat& s); 167 inline const subview_field<oT> operator()(const uword in_row1, const uword in_col1, const SizeMat& s) const; 168 169 inline subview_field<oT> operator()(const uword in_row1, const uword in_col1, const uword in_slice1, const SizeCube& s); 170 inline const subview_field<oT> operator()(const uword in_row1, const uword in_col1, const uword in_slice1, const SizeCube& s) const; 171 172 173 arma_cold inline void print( const std::string extra_text = "") const; 174 arma_cold inline void print(std::ostream& user_stream, const std::string extra_text = "") const; 175 176 inline const field& for_each(const std::function< void( oT&) >& F); 177 inline const field& for_each(const std::function< void(const oT&) >& F) const; 178 179 inline const field& fill(const oT& x); 180 181 inline void reset(); 182 inline void reset_objects(); 183 184 arma_inline bool is_empty() const; 185 186 187 arma_inline arma_warn_unused bool in_range(const uword i) const; 188 arma_inline arma_warn_unused bool in_range(const span& x) const; 189 190 arma_inline arma_warn_unused bool in_range(const uword in_row, const uword in_col) const; 191 arma_inline arma_warn_unused bool in_range(const span& row_span, const uword in_col) const; 192 arma_inline arma_warn_unused bool in_range(const uword in_row, const span& col_span) const; 193 arma_inline arma_warn_unused bool in_range(const span& row_span, const span& col_span) const; 194 195 arma_inline arma_warn_unused bool in_range(const uword in_row, const uword in_col, const SizeMat& s) const; 196 197 arma_inline arma_warn_unused bool in_range(const uword in_row, const uword in_col, const uword in_slice) const; 198 arma_inline arma_warn_unused bool in_range(const span& row_span, const span& col_span, const span& slice_span) const; 199 200 arma_inline arma_warn_unused bool in_range(const uword in_row, const uword in_col, const uword in_slice, const SizeCube& s) const; 201 202 203 inline arma_cold bool save(const std::string name, const file_type type = arma_binary) const; 204 inline arma_cold bool save( std::ostream& os, const file_type type = arma_binary) const; 205 206 inline arma_cold bool load(const std::string name, const file_type type = auto_detect); 207 inline arma_cold bool load( std::istream& is, const file_type type = auto_detect); 208 209 210 inline arma_cold bool quiet_save(const std::string name, const file_type type = arma_binary) const; 211 inline arma_cold bool quiet_save( std::ostream& os, const file_type type = arma_binary) const; 212 213 inline arma_cold bool quiet_load(const std::string name, const file_type type = auto_detect); 214 inline arma_cold bool quiet_load( std::istream& is, const file_type type = auto_detect); 215 216 217 // for container-like functionality 218 219 typedef oT value_type; 220 typedef uword size_type; 221 222 223 class iterator 224 { 225 public: 226 227 inline iterator(field<oT>& in_M, const bool at_end = false); 228 229 inline oT& operator* (); 230 231 inline iterator& operator++(); 232 inline void operator++(int); 233 234 inline iterator& operator--(); 235 inline void operator--(int); 236 237 inline bool operator!=(const iterator& X) const; 238 inline bool operator==(const iterator& X) const; 239 240 arma_aligned field<oT>& M; 241 arma_aligned uword i; 242 }; 243 244 245 class const_iterator 246 { 247 public: 248 249 const_iterator(const field<oT>& in_M, const bool at_end = false); 250 const_iterator(const iterator& X); 251 252 inline const oT& operator*() const; 253 254 inline const_iterator& operator++(); 255 inline void operator++(int); 256 257 inline const_iterator& operator--(); 258 inline void operator--(int); 259 260 inline bool operator!=(const const_iterator& X) const; 261 inline bool operator==(const const_iterator& X) const; 262 263 arma_aligned const field<oT>& M; 264 arma_aligned uword i; 265 }; 266 267 inline iterator begin(); 268 inline const_iterator begin() const; 269 inline const_iterator cbegin() const; 270 271 inline iterator end(); 272 inline const_iterator end() const; 273 inline const_iterator cend() const; 274 275 inline void clear(); 276 inline bool empty() const; 277 inline uword size() const; 278 279 280 private: 281 282 inline void init(const field<oT>& x); 283 inline void init(const uword n_rows_in, const uword n_cols_in); 284 inline void init(const uword n_rows_in, const uword n_cols_in, const uword n_slices_in); 285 286 inline void delete_objects(); 287 inline void create_objects(); 288 289 friend class field_aux; 290 friend class subview_field<oT>; 291 292 293 public: 294 295 #ifdef ARMA_EXTRA_FIELD_PROTO 296 #include ARMA_INCFILE_WRAP(ARMA_EXTRA_FIELD_PROTO) 297 #endif 298 }; 299 300 301 302 class field_aux 303 { 304 public: 305 306 template<typename oT> inline static void reset_objects(field< oT >& x); 307 template<typename eT> inline static void reset_objects(field< Mat<eT> >& x); 308 template<typename eT> inline static void reset_objects(field< Col<eT> >& x); 309 template<typename eT> inline static void reset_objects(field< Row<eT> >& x); 310 template<typename eT> inline static void reset_objects(field< Cube<eT> >& x); 311 inline static void reset_objects(field< std::string >& x); 312 313 314 template<typename oT> inline static bool save(const field< oT >& x, const std::string& name, const file_type type, std::string& err_msg); 315 template<typename oT> inline static bool save(const field< oT >& x, std::ostream& os, const file_type type, std::string& err_msg); 316 template<typename oT> inline static bool load( field< oT >& x, const std::string& name, const file_type type, std::string& err_msg); 317 template<typename oT> inline static bool load( field< oT >& x, std::istream& is, const file_type type, std::string& err_msg); 318 319 template<typename eT> inline static bool save(const field< Mat<eT> >& x, const std::string& name, const file_type type, std::string& err_msg); 320 template<typename eT> inline static bool save(const field< Mat<eT> >& x, std::ostream& os, const file_type type, std::string& err_msg); 321 template<typename eT> inline static bool load( field< Mat<eT> >& x, const std::string& name, const file_type type, std::string& err_msg); 322 template<typename eT> inline static bool load( field< Mat<eT> >& x, std::istream& is, const file_type type, std::string& err_msg); 323 324 template<typename eT> inline static bool save(const field< Col<eT> >& x, const std::string& name, const file_type type, std::string& err_msg); 325 template<typename eT> inline static bool save(const field< Col<eT> >& x, std::ostream& os, const file_type type, std::string& err_msg); 326 template<typename eT> inline static bool load( field< Col<eT> >& x, const std::string& name, const file_type type, std::string& err_msg); 327 template<typename eT> inline static bool load( field< Col<eT> >& x, std::istream& is, const file_type type, std::string& err_msg); 328 329 template<typename eT> inline static bool save(const field< Row<eT> >& x, const std::string& name, const file_type type, std::string& err_msg); 330 template<typename eT> inline static bool save(const field< Row<eT> >& x, std::ostream& os, const file_type type, std::string& err_msg); 331 template<typename eT> inline static bool load( field< Row<eT> >& x, const std::string& name, const file_type type, std::string& err_msg); 332 template<typename eT> inline static bool load( field< Row<eT> >& x, std::istream& is, const file_type type, std::string& err_msg); 333 334 template<typename eT> inline static bool save(const field< Cube<eT> >& x, const std::string& name, const file_type type, std::string& err_msg); 335 template<typename eT> inline static bool save(const field< Cube<eT> >& x, std::ostream& os, const file_type type, std::string& err_msg); 336 template<typename eT> inline static bool load( field< Cube<eT> >& x, const std::string& name, const file_type type, std::string& err_msg); 337 template<typename eT> inline static bool load( field< Cube<eT> >& x, std::istream& is, const file_type type, std::string& err_msg); 338 339 inline static bool save(const field< std::string >& x, const std::string& name, const file_type type, std::string& err_msg); 340 inline static bool save(const field< std::string >& x, std::ostream& os, const file_type type, std::string& err_msg); 341 inline static bool load( field< std::string >& x, const std::string& name, const file_type type, std::string& err_msg); 342 inline static bool load( field< std::string >& x, std::istream& is, const file_type type, std::string& err_msg); 343 344 }; 345 346 347 //! @} 348