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