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 ProxyCube
20 //! @{
21 
22 
23 
24 template<typename T1>
25 struct ProxyCube
26   {
ProxyCubeProxyCube27   inline ProxyCube(const T1&)
28     {
29     arma_type_check(( is_arma_cube_type<T1>::value == false ));
30     }
31   };
32 
33 
34 
35 // ea_type is the "element accessor" type,
36 // which can provide access to elements via operator[]
37 
38 template<typename eT>
39 struct ProxyCube< Cube<eT> >
40   {
41   typedef eT                                       elem_type;
42   typedef typename get_pod_type<elem_type>::result pod_type;
43   typedef Cube<eT>                                 stored_type;
44   typedef const eT*                                ea_type;
45   typedef const Cube<eT>&                          aligned_ea_type;
46 
47   static constexpr bool use_at      = false;
48   static constexpr bool use_mp      = false;
49   static constexpr bool has_subview = false;
50 
51   arma_aligned const Cube<eT>& Q;
52 
ProxyCubeProxyCube53   inline explicit ProxyCube(const Cube<eT>& A)
54     : Q(A)
55     {
56     arma_extra_debug_sigprint();
57     }
58 
get_n_rowsProxyCube59   arma_inline uword get_n_rows()       const { return Q.n_rows;       }
get_n_colsProxyCube60   arma_inline uword get_n_cols()       const { return Q.n_cols;       }
get_n_elem_sliceProxyCube61   arma_inline uword get_n_elem_slice() const { return Q.n_elem_slice; }
get_n_slicesProxyCube62   arma_inline uword get_n_slices()     const { return Q.n_slices;     }
get_n_elemProxyCube63   arma_inline uword get_n_elem()       const { return Q.n_elem;       }
64 
operator []ProxyCube65   arma_inline elem_type operator[] (const uword i)                               const { return Q[i];          }
atProxyCube66   arma_inline elem_type at         (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); }
at_altProxyCube67   arma_inline elem_type at_alt     (const uword i)                               const { return Q.at_alt(i);   }
68 
get_eaProxyCube69   arma_inline         ea_type         get_ea() const { return Q.memptr(); }
get_aligned_eaProxyCube70   arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
71 
72   template<typename eT2>
is_aliasProxyCube73   arma_inline bool is_alias(const Cube<eT2>& X) const { return (void_ptr(&Q) == void_ptr(&X)); }
74 
75   template<typename eT2>
has_overlapProxyCube76   arma_inline bool has_overlap(const subview_cube<eT2>& X) const { return is_alias(X.m); }
77 
is_alignedProxyCube78   arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
79   };
80 
81 
82 
83 template<typename eT, typename gen_type>
84 struct ProxyCube< GenCube<eT, gen_type> >
85   {
86   typedef          eT                              elem_type;
87   typedef typename get_pod_type<elem_type>::result pod_type;
88   typedef GenCube<eT, gen_type>                    stored_type;
89   typedef const GenCube<eT, gen_type>&             ea_type;
90   typedef const GenCube<eT, gen_type>&             aligned_ea_type;
91 
92   static constexpr bool use_at      = false;
93   static constexpr bool use_mp      = false;
94   static constexpr bool has_subview = false;
95 
96   arma_aligned const GenCube<eT, gen_type>& Q;
97 
ProxyCubeProxyCube98   inline explicit ProxyCube(const GenCube<eT, gen_type>& A)
99     : Q(A)
100     {
101     arma_extra_debug_sigprint();
102     }
103 
get_n_rowsProxyCube104   arma_inline uword get_n_rows()       const { return Q.n_rows;                     }
get_n_colsProxyCube105   arma_inline uword get_n_cols()       const { return Q.n_cols;                     }
get_n_elem_sliceProxyCube106   arma_inline uword get_n_elem_slice() const { return Q.n_rows*Q.n_cols;            }
get_n_slicesProxyCube107   arma_inline uword get_n_slices()     const { return Q.n_slices;                   }
get_n_elemProxyCube108   arma_inline uword get_n_elem()       const { return Q.n_rows*Q.n_cols*Q.n_slices; }
109 
operator []ProxyCube110   arma_inline elem_type operator[] (const uword i)                               const { return Q[i];          }
atProxyCube111   arma_inline elem_type at         (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); }
at_altProxyCube112   arma_inline elem_type at_alt     (const uword i)                               const { return Q[i];          }
113 
get_eaProxyCube114   arma_inline         ea_type         get_ea() const { return Q; }
get_aligned_eaProxyCube115   arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
116 
117   template<typename eT2>
is_aliasProxyCube118   constexpr bool is_alias(const Cube<eT2>&) const { return false; }
119 
120   template<typename eT2>
has_overlapProxyCube121   constexpr bool has_overlap(const subview_cube<eT2>&) const { return false; }
122 
is_alignedProxyCube123   arma_inline bool is_aligned() const { return GenCube<eT, gen_type>::is_simple; }
124   };
125 
126 
127 
128 template<typename eT>
129 struct ProxyCube< GenCube<eT, gen_randu> >
130   {
131   typedef eT                                       elem_type;
132   typedef typename get_pod_type<elem_type>::result pod_type;
133   typedef Cube<eT>                                 stored_type;
134   typedef const eT*                                ea_type;
135   typedef const Cube<eT>&                          aligned_ea_type;
136 
137   static constexpr bool use_at      = false;
138   static constexpr bool use_mp      = false;
139   static constexpr bool has_subview = false;
140 
141   arma_aligned const Cube<eT> Q;
142 
ProxyCubeProxyCube143   inline explicit ProxyCube(const GenCube<eT, gen_randu>& A)
144     : Q(A)
145     {
146     arma_extra_debug_sigprint();
147     }
148 
get_n_rowsProxyCube149   arma_inline uword get_n_rows()       const { return Q.n_rows;       }
get_n_colsProxyCube150   arma_inline uword get_n_cols()       const { return Q.n_cols;       }
get_n_elem_sliceProxyCube151   arma_inline uword get_n_elem_slice() const { return Q.n_elem_slice; }
get_n_slicesProxyCube152   arma_inline uword get_n_slices()     const { return Q.n_slices;     }
get_n_elemProxyCube153   arma_inline uword get_n_elem()       const { return Q.n_elem;       }
154 
operator []ProxyCube155   arma_inline elem_type operator[] (const uword i)                               const { return Q[i];          }
atProxyCube156   arma_inline elem_type at         (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); }
at_altProxyCube157   arma_inline elem_type at_alt     (const uword i)                               const { return Q.at_alt(i);   }
158 
get_eaProxyCube159   arma_inline         ea_type         get_ea() const { return Q.memptr(); }
get_aligned_eaProxyCube160   arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
161 
162   template<typename eT2>
is_aliasProxyCube163   constexpr bool is_alias(const Cube<eT2>&) const { return false; }
164 
165   template<typename eT2>
has_overlapProxyCube166   constexpr bool has_overlap(const subview_cube<eT2>&) const { return false; }
167 
is_alignedProxyCube168   arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
169   };
170 
171 
172 
173 template<typename eT>
174 struct ProxyCube< GenCube<eT, gen_randn> >
175   {
176   typedef eT                                       elem_type;
177   typedef typename get_pod_type<elem_type>::result pod_type;
178   typedef Cube<eT>                                 stored_type;
179   typedef const eT*                                ea_type;
180   typedef const Cube<eT>&                          aligned_ea_type;
181 
182   static constexpr bool use_at      = false;
183   static constexpr bool use_mp      = false;
184   static constexpr bool has_subview = false;
185 
186   arma_aligned const Cube<eT> Q;
187 
ProxyCubeProxyCube188   inline explicit ProxyCube(const GenCube<eT, gen_randn>& A)
189     : Q(A)
190     {
191     arma_extra_debug_sigprint();
192     }
193 
get_n_rowsProxyCube194   arma_inline uword get_n_rows()       const { return Q.n_rows;       }
get_n_colsProxyCube195   arma_inline uword get_n_cols()       const { return Q.n_cols;       }
get_n_elem_sliceProxyCube196   arma_inline uword get_n_elem_slice() const { return Q.n_elem_slice; }
get_n_slicesProxyCube197   arma_inline uword get_n_slices()     const { return Q.n_slices;     }
get_n_elemProxyCube198   arma_inline uword get_n_elem()       const { return Q.n_elem;       }
199 
operator []ProxyCube200   arma_inline elem_type operator[] (const uword i)                               const { return Q[i];          }
atProxyCube201   arma_inline elem_type at         (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); }
at_altProxyCube202   arma_inline elem_type at_alt     (const uword i)                               const { return Q.at_alt(i);   }
203 
get_eaProxyCube204   arma_inline         ea_type         get_ea() const { return Q.memptr(); }
get_aligned_eaProxyCube205   arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
206 
207   template<typename eT2>
is_aliasProxyCube208   constexpr bool is_alias(const Cube<eT2>&) const { return false; }
209 
210   template<typename eT2>
has_overlapProxyCube211   constexpr bool has_overlap(const subview_cube<eT2>&) const { return false; }
212 
is_alignedProxyCube213   arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
214   };
215 
216 
217 
218 template<typename T1, typename op_type>
219 struct ProxyCube< OpCube<T1, op_type> >
220   {
221   typedef typename T1::elem_type                   elem_type;
222   typedef typename get_pod_type<elem_type>::result pod_type;
223   typedef Cube<elem_type>                          stored_type;
224   typedef const elem_type*                         ea_type;
225   typedef const Cube<elem_type>&                   aligned_ea_type;
226 
227   static constexpr bool use_at      = false;
228   static constexpr bool use_mp      = false;
229   static constexpr bool has_subview = false;
230 
231   arma_aligned const Cube<elem_type> Q;
232 
ProxyCubeProxyCube233   inline explicit ProxyCube(const OpCube<T1, op_type>& A)
234     : Q(A)
235     {
236     arma_extra_debug_sigprint();
237     }
238 
get_n_rowsProxyCube239   arma_inline uword get_n_rows()       const { return Q.n_rows;       }
get_n_colsProxyCube240   arma_inline uword get_n_cols()       const { return Q.n_cols;       }
get_n_elem_sliceProxyCube241   arma_inline uword get_n_elem_slice() const { return Q.n_elem_slice; }
get_n_slicesProxyCube242   arma_inline uword get_n_slices()     const { return Q.n_slices;     }
get_n_elemProxyCube243   arma_inline uword get_n_elem()       const { return Q.n_elem;       }
244 
operator []ProxyCube245   arma_inline elem_type operator[] (const uword i)                               const { return Q[i];          }
atProxyCube246   arma_inline elem_type at         (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); }
at_altProxyCube247   arma_inline elem_type at_alt     (const uword i)                               const { return Q.at_alt(i);   }
248 
get_eaProxyCube249   arma_inline         ea_type         get_ea() const { return Q.memptr(); }
get_aligned_eaProxyCube250   arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
251 
252   template<typename eT2>
is_aliasProxyCube253   constexpr bool is_alias(const Cube<eT2>&) const { return false; }
254 
255   template<typename eT2>
has_overlapProxyCube256   constexpr bool has_overlap(const subview_cube<eT2>&) const { return false; }
257 
is_alignedProxyCube258   arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
259   };
260 
261 
262 
263 template<typename T1, typename T2, typename glue_type>
264 struct ProxyCube< GlueCube<T1, T2, glue_type> >
265   {
266   typedef typename T1::elem_type                   elem_type;
267   typedef typename get_pod_type<elem_type>::result pod_type;
268   typedef Cube<elem_type>                          stored_type;
269   typedef const elem_type*                         ea_type;
270   typedef const Cube<elem_type>&                   aligned_ea_type;
271 
272   static constexpr bool use_at      = false;
273   static constexpr bool use_mp      = false;
274   static constexpr bool has_subview = false;
275 
276   arma_aligned const Cube<elem_type> Q;
277 
ProxyCubeProxyCube278   inline explicit ProxyCube(const GlueCube<T1, T2, glue_type>& A)
279     : Q(A)
280     {
281     arma_extra_debug_sigprint();
282     }
283 
get_n_rowsProxyCube284   arma_inline uword get_n_rows()       const { return Q.n_rows;       }
get_n_colsProxyCube285   arma_inline uword get_n_cols()       const { return Q.n_cols;       }
get_n_elem_sliceProxyCube286   arma_inline uword get_n_elem_slice() const { return Q.n_elem_slice; }
get_n_slicesProxyCube287   arma_inline uword get_n_slices()     const { return Q.n_slices;     }
get_n_elemProxyCube288   arma_inline uword get_n_elem()       const { return Q.n_elem;       }
289 
operator []ProxyCube290   arma_inline elem_type operator[] (const uword i)                               const { return Q[i];          }
atProxyCube291   arma_inline elem_type at         (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); }
at_altProxyCube292   arma_inline elem_type at_alt     (const uword i)                               const { return Q.at_alt(i);   }
293 
get_eaProxyCube294   arma_inline         ea_type         get_ea() const { return Q.memptr(); }
get_aligned_eaProxyCube295   arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
296 
297   template<typename eT2>
is_aliasProxyCube298   constexpr bool is_alias(const Cube<eT2>&) const { return false; }
299 
300   template<typename eT2>
has_overlapProxyCube301   constexpr bool has_overlap(const subview_cube<eT2>&) const { return false; }
302 
is_alignedProxyCube303   arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
304   };
305 
306 
307 
308 template<typename eT>
309 struct ProxyCube< subview_cube<eT> >
310   {
311   typedef eT                                       elem_type;
312   typedef typename get_pod_type<elem_type>::result pod_type;
313   typedef subview_cube<eT>                         stored_type;
314   typedef const subview_cube<eT>&                  ea_type;
315   typedef const subview_cube<eT>&                  aligned_ea_type;
316 
317   static constexpr bool use_at      = true;
318   static constexpr bool use_mp      = false;
319   static constexpr bool has_subview = true;
320 
321   arma_aligned const subview_cube<eT>& Q;
322 
ProxyCubeProxyCube323   inline explicit ProxyCube(const subview_cube<eT>& A)
324     : Q(A)
325     {
326     arma_extra_debug_sigprint();
327     }
328 
get_n_rowsProxyCube329   arma_inline uword get_n_rows()       const { return Q.n_rows;       }
get_n_colsProxyCube330   arma_inline uword get_n_cols()       const { return Q.n_cols;       }
get_n_elem_sliceProxyCube331   arma_inline uword get_n_elem_slice() const { return Q.n_elem_slice; }
get_n_slicesProxyCube332   arma_inline uword get_n_slices()     const { return Q.n_slices;     }
get_n_elemProxyCube333   arma_inline uword get_n_elem()       const { return Q.n_elem;       }
334 
operator []ProxyCube335   arma_inline elem_type operator[] (const uword i)                               const { return Q[i];          }
atProxyCube336   arma_inline elem_type at         (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); }
at_altProxyCube337   arma_inline elem_type at_alt     (const uword i)                               const { return Q.at_alt(i);   }
338 
get_eaProxyCube339   arma_inline         ea_type         get_ea() const { return Q; }
get_aligned_eaProxyCube340   arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
341 
342   template<typename eT2>
is_aliasProxyCube343   arma_inline bool is_alias(const Cube<eT2>& X) const { return (void_ptr(&(Q.m)) == void_ptr(&X)); }
344 
345   template<typename eT2>
has_overlapProxyCube346   arma_inline bool has_overlap(const subview_cube<eT2>& X) const { return Q.check_overlap(X); }
347 
is_alignedProxyCube348   constexpr bool is_aligned() const { return false; }
349   };
350 
351 
352 
353 template<typename eT, typename T1>
354 struct ProxyCube< subview_cube_slices<eT,T1> >
355   {
356   typedef eT                                       elem_type;
357   typedef typename get_pod_type<elem_type>::result pod_type;
358   typedef Cube<eT>                                 stored_type;
359   typedef const eT*                                ea_type;
360   typedef const Cube<eT>&                          aligned_ea_type;
361 
362   static constexpr bool use_at      = false;
363   static constexpr bool use_mp      = false;
364   static constexpr bool has_subview = false;
365 
366   arma_aligned const Cube<eT> Q;
367 
ProxyCubeProxyCube368   inline explicit ProxyCube(const subview_cube_slices<eT,T1>& A)
369     : Q(A)
370     {
371     arma_extra_debug_sigprint();
372     }
373 
get_n_rowsProxyCube374   arma_inline uword get_n_rows()       const { return Q.n_rows;       }
get_n_colsProxyCube375   arma_inline uword get_n_cols()       const { return Q.n_cols;       }
get_n_elem_sliceProxyCube376   arma_inline uword get_n_elem_slice() const { return Q.n_elem_slice; }
get_n_slicesProxyCube377   arma_inline uword get_n_slices()     const { return Q.n_slices;     }
get_n_elemProxyCube378   arma_inline uword get_n_elem()       const { return Q.n_elem;       }
379 
operator []ProxyCube380   arma_inline elem_type operator[] (const uword i)                               const { return Q[i];          }
atProxyCube381   arma_inline elem_type at         (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); }
at_altProxyCube382   arma_inline elem_type at_alt     (const uword i)                               const { return Q.at_alt(i);   }
383 
get_eaProxyCube384   arma_inline         ea_type         get_ea() const { return Q.memptr(); }
get_aligned_eaProxyCube385   arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
386 
387   template<typename eT2>
is_aliasProxyCube388   constexpr bool is_alias(const Cube<eT2>&) const { return false; }
389 
390   template<typename eT2>
has_overlapProxyCube391   constexpr bool has_overlap(const subview_cube<eT2>&) const { return false; }
392 
is_alignedProxyCube393   arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
394   };
395 
396 
397 
398 template<typename T1, typename eop_type>
399 struct ProxyCube< eOpCube<T1, eop_type > >
400   {
401   typedef typename T1::elem_type                   elem_type;
402   typedef typename get_pod_type<elem_type>::result pod_type;
403   typedef eOpCube<T1, eop_type>                    stored_type;
404   typedef const eOpCube<T1, eop_type>&             ea_type;
405   typedef const eOpCube<T1, eop_type>&             aligned_ea_type;
406 
407   static constexpr bool use_at      = eOpCube<T1, eop_type>::use_at;
408   static constexpr bool use_mp      = eOpCube<T1, eop_type>::use_mp;
409   static constexpr bool has_subview = eOpCube<T1, eop_type>::has_subview;
410 
411   arma_aligned const eOpCube<T1, eop_type>& Q;
412 
ProxyCubeProxyCube413   inline explicit ProxyCube(const eOpCube<T1, eop_type>& A)
414     : Q(A)
415     {
416     arma_extra_debug_sigprint();
417     }
418 
get_n_rowsProxyCube419   arma_inline uword get_n_rows()       const { return Q.get_n_rows();       }
get_n_colsProxyCube420   arma_inline uword get_n_cols()       const { return Q.get_n_cols();       }
get_n_elem_sliceProxyCube421   arma_inline uword get_n_elem_slice() const { return Q.get_n_elem_slice(); }
get_n_slicesProxyCube422   arma_inline uword get_n_slices()     const { return Q.get_n_slices();     }
get_n_elemProxyCube423   arma_inline uword get_n_elem()       const { return Q.get_n_elem();       }
424 
operator []ProxyCube425   arma_inline elem_type operator[] (const uword i)                               const { return Q[i];          }
atProxyCube426   arma_inline elem_type at         (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); }
at_altProxyCube427   arma_inline elem_type at_alt     (const uword i)                               const { return Q.at_alt(i);   }
428 
get_eaProxyCube429   arma_inline         ea_type         get_ea() const { return Q; }
get_aligned_eaProxyCube430   arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
431 
432   template<typename eT2>
is_aliasProxyCube433   arma_inline bool is_alias(const Cube<eT2>& X) const { return Q.P.is_alias(X); }
434 
435   template<typename eT2>
has_overlapProxyCube436   arma_inline bool has_overlap(const subview_cube<eT2>& X) const { return Q.P.has_overlap(X); }
437 
is_alignedProxyCube438   arma_inline bool is_aligned() const { return Q.P.is_aligned(); }
439   };
440 
441 
442 
443 template<typename T1, typename T2, typename eglue_type>
444 struct ProxyCube< eGlueCube<T1, T2, eglue_type > >
445   {
446   typedef typename T1::elem_type                   elem_type;
447   typedef typename get_pod_type<elem_type>::result pod_type;
448   typedef eGlueCube<T1, T2, eglue_type>            stored_type;
449   typedef const eGlueCube<T1, T2, eglue_type>&     ea_type;
450   typedef const eGlueCube<T1, T2, eglue_type>&     aligned_ea_type;
451 
452   static constexpr bool use_at      = eGlueCube<T1, T2, eglue_type>::use_at;
453   static constexpr bool use_mp      = eGlueCube<T1, T2, eglue_type>::use_mp;
454   static constexpr bool has_subview = eGlueCube<T1, T2, eglue_type>::has_subview;
455 
456   arma_aligned const eGlueCube<T1, T2, eglue_type>& Q;
457 
ProxyCubeProxyCube458   inline explicit ProxyCube(const eGlueCube<T1, T2, eglue_type>& A)
459     : Q(A)
460     {
461     arma_extra_debug_sigprint();
462     }
463 
get_n_rowsProxyCube464   arma_inline uword get_n_rows()       const { return Q.get_n_rows();       }
get_n_colsProxyCube465   arma_inline uword get_n_cols()       const { return Q.get_n_cols();       }
get_n_elem_sliceProxyCube466   arma_inline uword get_n_elem_slice() const { return Q.get_n_elem_slice(); }
get_n_slicesProxyCube467   arma_inline uword get_n_slices()     const { return Q.get_n_slices();     }
get_n_elemProxyCube468   arma_inline uword get_n_elem()       const { return Q.get_n_elem();       }
469 
operator []ProxyCube470   arma_inline elem_type operator[] (const uword i)                               const { return Q[i];          }
atProxyCube471   arma_inline elem_type at         (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); }
at_altProxyCube472   arma_inline elem_type at_alt     (const uword i)                               const { return Q.at_alt(i);   }
473 
get_eaProxyCube474   arma_inline         ea_type         get_ea() const { return Q; }
get_aligned_eaProxyCube475   arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
476 
477   template<typename eT2>
is_aliasProxyCube478   arma_inline bool is_alias(const Cube<eT2>& X) const { return (Q.P1.is_alias(X) || Q.P2.is_alias(X)); }
479 
480   template<typename eT2>
has_overlapProxyCube481   arma_inline bool has_overlap(const subview_cube<eT2>& X) const { return (Q.P1.has_overlap(X) || Q.P2.has_overlap(X)); }
482 
is_alignedProxyCube483   arma_inline bool is_aligned() const { return Q.P1.is_aligned() && Q.P2.is_aligned(); }
484   };
485 
486 
487 
488 template<typename out_eT, typename T1, typename op_type>
489 struct ProxyCube< mtOpCube<out_eT, T1, op_type> >
490   {
491   typedef          out_eT                       elem_type;
492   typedef typename get_pod_type<out_eT>::result pod_type;
493   typedef          Cube<out_eT>                 stored_type;
494   typedef          const elem_type*             ea_type;
495   typedef          const Cube<out_eT>&          aligned_ea_type;
496 
497   static constexpr bool use_at      = false;
498   static constexpr bool use_mp      = false;
499   static constexpr bool has_subview = false;
500 
501   arma_aligned const Cube<out_eT> Q;
502 
ProxyCubeProxyCube503   inline explicit ProxyCube(const mtOpCube<out_eT, T1, op_type>& A)
504     : Q(A)
505     {
506     arma_extra_debug_sigprint();
507     }
508 
get_n_rowsProxyCube509   arma_inline uword get_n_rows()       const { return Q.n_rows;       }
get_n_colsProxyCube510   arma_inline uword get_n_cols()       const { return Q.n_cols;       }
get_n_elem_sliceProxyCube511   arma_inline uword get_n_elem_slice() const { return Q.n_elem_slice; }
get_n_slicesProxyCube512   arma_inline uword get_n_slices()     const { return Q.n_slices;     }
get_n_elemProxyCube513   arma_inline uword get_n_elem()       const { return Q.n_elem;       }
514 
operator []ProxyCube515   arma_inline elem_type operator[] (const uword i)                               const { return Q[i];          }
atProxyCube516   arma_inline elem_type at         (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); }
at_altProxyCube517   arma_inline elem_type at_alt     (const uword i)                               const { return Q.at_alt(i);   }
518 
get_eaProxyCube519   arma_inline         ea_type         get_ea() const { return Q.memptr(); }
get_aligned_eaProxyCube520   arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
521 
522   template<typename eT2>
is_aliasProxyCube523   constexpr bool is_alias(const Cube<eT2>&) const { return false; }
524 
525   template<typename eT2>
has_overlapProxyCube526   constexpr bool has_overlap(const subview_cube<eT2>&) const { return false; }
527 
is_alignedProxyCube528   arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
529   };
530 
531 
532 
533 template<typename out_eT, typename T1, typename T2, typename glue_type>
534 struct ProxyCube< mtGlueCube<out_eT, T1, T2, glue_type > >
535   {
536   typedef          out_eT                       elem_type;
537   typedef typename get_pod_type<out_eT>::result pod_type;
538   typedef          Cube<out_eT>                 stored_type;
539   typedef          const elem_type*             ea_type;
540   typedef          const Cube<out_eT>&          aligned_ea_type;
541 
542   static constexpr bool use_at      = false;
543   static constexpr bool use_mp      = false;
544   static constexpr bool has_subview = false;
545 
546   arma_aligned const Cube<out_eT> Q;
547 
ProxyCubeProxyCube548   inline explicit ProxyCube(const mtGlueCube<out_eT, T1, T2, glue_type>& A)
549     : Q(A)
550     {
551     arma_extra_debug_sigprint();
552     }
553 
get_n_rowsProxyCube554   arma_inline uword get_n_rows()       const { return Q.n_rows;       }
get_n_colsProxyCube555   arma_inline uword get_n_cols()       const { return Q.n_cols;       }
get_n_elem_sliceProxyCube556   arma_inline uword get_n_elem_slice() const { return Q.n_elem_slice; }
get_n_slicesProxyCube557   arma_inline uword get_n_slices()     const { return Q.n_slices;     }
get_n_elemProxyCube558   arma_inline uword get_n_elem()       const { return Q.n_elem;       }
559 
operator []ProxyCube560   arma_inline elem_type operator[] (const uword i)                               const { return Q[i];          }
atProxyCube561   arma_inline elem_type at         (const uword r, const uword c, const uword s) const { return Q.at(r, c, s); }
at_altProxyCube562   arma_inline elem_type at_alt     (const uword i)                               const { return Q.at_alt(i);   }
563 
get_eaProxyCube564   arma_inline         ea_type         get_ea() const { return Q.memptr(); }
get_aligned_eaProxyCube565   arma_inline aligned_ea_type get_aligned_ea() const { return Q;          }
566 
567   template<typename eT2>
is_aliasProxyCube568   constexpr bool is_alias(const Cube<eT2>&) const { return false; }
569 
570   template<typename eT2>
has_overlapProxyCube571   constexpr bool has_overlap(const subview_cube<eT2>&) const { return false; }
572 
is_alignedProxyCube573   arma_inline bool is_aligned() const { return memory::is_aligned(Q.memptr()); }
574   };
575 
576 
577 
578 //! @}
579