Mercurial > octave
diff liboctave/array/idx-vector.h @ 31607:aac27ad79be6 stable
maint: Re-indent code after switch to using namespace macros.
* build-env.h, build-env.in.cc, Cell.h, __betainc__.cc, __eigs__.cc,
__ftp__.cc, __ichol__.cc, __ilu__.cc, __isprimelarge__.cc, __magick_read__.cc,
__pchip_deriv__.cc, amd.cc, base-text-renderer.cc, base-text-renderer.h,
besselj.cc, bitfcns.cc, bsxfun.cc, c-file-ptr-stream.h, call-stack.cc,
call-stack.h, ccolamd.cc, cellfun.cc, chol.cc, colamd.cc, dasrt.cc, data.cc,
debug.cc, defaults.cc, defaults.h, det.cc, display.cc, display.h, dlmread.cc,
dynamic-ld.cc, dynamic-ld.h, ellipj.cc, environment.cc, environment.h,
error.cc, error.h, errwarn.h, event-manager.cc, event-manager.h,
event-queue.cc, event-queue.h, fcn-info.cc, fcn-info.h, fft.cc, fft2.cc,
file-io.cc, filter.cc, find.cc, ft-text-renderer.cc, ft-text-renderer.h,
gcd.cc, gl-render.cc, gl-render.h, gl2ps-print.cc, gl2ps-print.h,
graphics-toolkit.cc, graphics-toolkit.h, graphics.cc, gsvd.cc, gtk-manager.cc,
gtk-manager.h, help.cc, help.h, hook-fcn.cc, hook-fcn.h, input.cc, input.h,
interpreter-private.cc, interpreter-private.h, interpreter.cc, interpreter.h,
inv.cc, jsondecode.cc, jsonencode.cc, latex-text-renderer.cc,
latex-text-renderer.h, load-path.cc, load-path.h, load-save.cc, load-save.h,
lookup.cc, ls-hdf5.cc, ls-mat4.cc, ls-mat5.cc, lsode.cc, lu.cc, mappers.cc,
matrix_type.cc, max.cc, mex.cc, mexproto.h, mxarray.h, mxtypes.in.h,
oct-errno.in.cc, oct-hdf5-types.cc, oct-hist.cc, oct-hist.h, oct-map.cc,
oct-map.h, oct-opengl.h, oct-prcstrm.h, oct-process.cc, oct-process.h,
oct-stdstrm.h, oct-stream.cc, oct-stream.h, oct-strstrm.h,
octave-default-image.h, ordqz.cc, ordschur.cc, pager.cc, pager.h, pinv.cc,
pow2.cc, pr-output.cc, psi.cc, qr.cc, quadcc.cc, rand.cc, regexp.cc,
settings.cc, settings.h, sighandlers.cc, sighandlers.h, sparse-xpow.cc,
sqrtm.cc, stack-frame.cc, stack-frame.h, stream-euler.cc, strfns.cc, svd.cc,
syminfo.cc, syminfo.h, symrcm.cc, symrec.cc, symrec.h, symscope.cc, symscope.h,
symtab.cc, symtab.h, sysdep.cc, sysdep.h, text-engine.cc, text-engine.h,
text-renderer.cc, text-renderer.h, time.cc, toplev.cc, typecast.cc,
url-handle-manager.cc, url-handle-manager.h, urlwrite.cc, utils.cc, utils.h,
variables.cc, variables.h, xdiv.cc, __delaunayn__.cc, __init_fltk__.cc,
__init_gnuplot__.cc, __ode15__.cc, __voronoi__.cc, audioread.cc, convhulln.cc,
gzip.cc, cdef-class.cc, cdef-class.h, cdef-fwd.h, cdef-manager.cc,
cdef-manager.h, cdef-method.cc, cdef-method.h, cdef-object.cc, cdef-object.h,
cdef-package.cc, cdef-package.h, cdef-property.cc, cdef-property.h,
cdef-utils.cc, cdef-utils.h, ov-base-diag.cc, ov-base-int.cc, ov-base-mat.cc,
ov-base-mat.h, ov-base-scalar.cc, ov-base.cc, ov-base.h, ov-bool-mat.cc,
ov-bool-mat.h, ov-bool-sparse.cc, ov-bool.cc, ov-builtin.h, ov-cell.cc,
ov-ch-mat.cc, ov-class.cc, ov-class.h, ov-classdef.cc, ov-classdef.h,
ov-complex.cc, ov-cx-diag.cc, ov-cx-mat.cc, ov-cx-sparse.cc, ov-dld-fcn.cc,
ov-dld-fcn.h, ov-fcn-handle.cc, ov-fcn-handle.h, ov-fcn.h, ov-float.cc,
ov-flt-complex.cc, ov-flt-cx-diag.cc, ov-flt-cx-mat.cc, ov-flt-re-diag.cc,
ov-flt-re-mat.cc, ov-flt-re-mat.h, ov-intx.h, ov-java.cc, ov-lazy-idx.cc,
ov-legacy-range.cc, ov-magic-int.cc, ov-mex-fcn.cc, ov-mex-fcn.h,
ov-null-mat.cc, ov-perm.cc, ov-range.cc, ov-re-diag.cc, ov-re-mat.cc,
ov-re-mat.h, ov-re-sparse.cc, ov-scalar.cc, ov-str-mat.cc, ov-struct.cc,
ov-typeinfo.cc, ov-typeinfo.h, ov-usr-fcn.cc, ov-usr-fcn.h, ov.cc, ov.h, ovl.h,
octave.cc, octave.h, op-b-sbm.cc, op-bm-sbm.cc, op-cs-scm.cc, op-fm-fcm.cc,
op-fs-fcm.cc, op-s-scm.cc, op-scm-cs.cc, op-scm-s.cc, op-sm-cs.cc, ops.h,
anon-fcn-validator.cc, anon-fcn-validator.h, bp-table.cc, bp-table.h,
comment-list.cc, comment-list.h, filepos.h, lex.h, oct-lvalue.cc, oct-lvalue.h,
parse.h, profiler.cc, profiler.h, pt-anon-scopes.cc, pt-anon-scopes.h,
pt-arg-list.cc, pt-arg-list.h, pt-args-block.cc, pt-args-block.h,
pt-array-list.cc, pt-array-list.h, pt-assign.cc, pt-assign.h, pt-binop.cc,
pt-binop.h, pt-bp.cc, pt-bp.h, pt-cbinop.cc, pt-cbinop.h, pt-cell.cc,
pt-cell.h, pt-check.cc, pt-check.h, pt-classdef.cc, pt-classdef.h, pt-cmd.h,
pt-colon.cc, pt-colon.h, pt-const.cc, pt-const.h, pt-decl.cc, pt-decl.h,
pt-eval.cc, pt-eval.h, pt-except.cc, pt-except.h, pt-exp.cc, pt-exp.h,
pt-fcn-handle.cc, pt-fcn-handle.h, pt-id.cc, pt-id.h, pt-idx.cc, pt-idx.h,
pt-jump.h, pt-loop.cc, pt-loop.h, pt-mat.cc, pt-mat.h, pt-misc.cc, pt-misc.h,
pt-pr-code.cc, pt-pr-code.h, pt-select.cc, pt-select.h, pt-spmd.cc, pt-spmd.h,
pt-stmt.cc, pt-stmt.h, pt-tm-const.cc, pt-tm-const.h, pt-unop.cc, pt-unop.h,
pt-walk.cc, pt-walk.h, pt.cc, pt.h, token.cc, token.h, Range.cc, Range.h,
idx-vector.cc, idx-vector.h, range-fwd.h, CollocWt.cc, CollocWt.h,
aepbalance.cc, aepbalance.h, chol.cc, chol.h, gepbalance.cc, gepbalance.h,
gsvd.cc, gsvd.h, hess.cc, hess.h, lo-mappers.cc, lo-mappers.h, lo-specfun.cc,
lo-specfun.h, lu.cc, lu.h, oct-convn.cc, oct-convn.h, oct-fftw.cc, oct-fftw.h,
oct-norm.cc, oct-norm.h, oct-rand.cc, oct-rand.h, oct-spparms.cc,
oct-spparms.h, qr.cc, qr.h, qrp.cc, qrp.h, randgamma.cc, randgamma.h,
randmtzig.cc, randmtzig.h, randpoisson.cc, randpoisson.h, schur.cc, schur.h,
sparse-chol.cc, sparse-chol.h, sparse-lu.cc, sparse-lu.h, sparse-qr.cc,
sparse-qr.h, svd.cc, svd.h, child-list.cc, child-list.h, dir-ops.cc, dir-ops.h,
file-ops.cc, file-ops.h, file-stat.cc, file-stat.h, lo-sysdep.cc, lo-sysdep.h,
lo-sysinfo.cc, lo-sysinfo.h, mach-info.cc, mach-info.h, oct-env.cc, oct-env.h,
oct-group.cc, oct-group.h, oct-password.cc, oct-password.h, oct-syscalls.cc,
oct-syscalls.h, oct-time.cc, oct-time.h, oct-uname.cc, oct-uname.h,
action-container.cc, action-container.h, base-list.h, cmd-edit.cc, cmd-edit.h,
cmd-hist.cc, cmd-hist.h, f77-fcn.h, file-info.cc, file-info.h,
lo-array-errwarn.cc, lo-array-errwarn.h, lo-hash.cc, lo-hash.h, lo-ieee.h,
lo-regexp.cc, lo-regexp.h, lo-utils.cc, lo-utils.h, oct-base64.cc,
oct-base64.h, oct-glob.cc, oct-glob.h, oct-inttypes.h, oct-mutex.cc,
oct-mutex.h, oct-refcount.h, oct-shlib.cc, oct-shlib.h, oct-sparse.cc,
oct-sparse.h, oct-string.h, octave-preserve-stream-state.h, pathsearch.cc,
pathsearch.h, quit.cc, quit.h, unwind-prot.cc, unwind-prot.h, url-transfer.cc,
url-transfer.h:
Re-indent code after switch to using namespace macros.
author | Rik <rik@octave.org> |
---|---|
date | Thu, 01 Dec 2022 18:02:15 -0800 |
parents | e88a07dec498 |
children | 597f3ee61a48 |
line wrap: on
line diff
--- a/liboctave/array/idx-vector.h Thu Dec 01 14:23:45 2022 -0800 +++ b/liboctave/array/idx-vector.h Thu Dec 01 18:02:15 2022 -0800 @@ -44,992 +44,992 @@ OCTAVE_BEGIN_NAMESPACE(octave) - // Design rationale: - // - // idx_vector is a reference-counting, polymorphic pointer, that can - // contain 4 types of index objects: a magic colon, a range, a scalar, - // or an index vector. - // - // Polymorphic methods for single element access are provided, as well - // as templates implementing "early dispatch", i.e., hoisting the checks - // for index type out of loops. +// Design rationale: +// +// idx_vector is a reference-counting, polymorphic pointer, that can +// contain 4 types of index objects: a magic colon, a range, a scalar, +// or an index vector. +// +// Polymorphic methods for single element access are provided, as well +// as templates implementing "early dispatch", i.e., hoisting the checks +// for index type out of loops. + +class +OCTAVE_API +idx_vector +{ +public: + + enum idx_class_type + { + class_invalid = -1, + class_colon = 0, + class_range, + class_scalar, + class_vector, + class_mask + }; + + template <typename T, typename D> friend class std::unique_ptr; + +private: + + class OCTAVE_API idx_base_rep + { + public: + + idx_base_rep (void) : m_count (1) { } + + // No copying! + + idx_base_rep (const idx_base_rep&) = delete; - class - OCTAVE_API - idx_vector + idx_base_rep& operator = (const idx_base_rep&) = delete; + + virtual ~idx_base_rep (void) = default; + + // Non-range-checking element query. + virtual octave_idx_type xelem (octave_idx_type i) const = 0; + + // Range-checking element query. + virtual octave_idx_type checkelem (octave_idx_type i) const = 0; + + // Length of the index vector. + virtual octave_idx_type length (octave_idx_type n) const = 0; + + // The maximum index + 1. The actual dimension is passed in. + virtual octave_idx_type extent (octave_idx_type n) const = 0; + + // Index class. + virtual idx_class_type idx_class (void) const { return class_invalid; } + + // Sorts, maybe uniqifies, and returns a clone object pointer. + virtual idx_base_rep * sort_uniq_clone (bool uniq = false) = 0; + // Sorts, and returns a sorting permutation (aka Array::sort). + virtual idx_base_rep * sort_idx (Array<octave_idx_type>&) = 0; + + // Checks whether the index is colon or a range equivalent to colon. + virtual bool is_colon_equiv (octave_idx_type) const { return false; } + + // The original dimensions of object (used when subscribing by matrices). + virtual dim_vector orig_dimensions (void) const { return dim_vector (); } + + // i/o + virtual std::ostream& print (std::ostream& os) const = 0; + + virtual Array<octave_idx_type> as_array (void); + + refcount<octave_idx_type> m_count; + }; + + // The magic colon index. + class OCTAVE_API idx_colon_rep : public idx_base_rep { public: - enum idx_class_type + idx_colon_rep (void) = default; + + OCTAVE_API idx_colon_rep (char c); + + // No copying! + + idx_colon_rep (const idx_colon_rep& idx) = delete; + + idx_colon_rep& operator = (const idx_colon_rep& idx) = delete; + + octave_idx_type xelem (octave_idx_type i) const { return i; } + + OCTAVE_API octave_idx_type checkelem (octave_idx_type i) const; + + octave_idx_type length (octave_idx_type n) const { return n; } + + octave_idx_type extent (octave_idx_type n) const { return n; } + + idx_class_type idx_class (void) const { return class_colon; } + + idx_base_rep * sort_uniq_clone (bool = false) + { m_count++; return this; } + + OCTAVE_NORETURN idx_base_rep * sort_idx (Array<octave_idx_type>&); + + bool is_colon_equiv (octave_idx_type) const { return true; } + + OCTAVE_API std::ostream& print (std::ostream& os) const; + }; + + // To distinguish the "direct" constructors that blindly trust the data. + enum direct { DIRECT }; + + // The integer range index. + class OCTAVE_API idx_range_rep : public idx_base_rep + { + public: + + idx_range_rep (void) = delete; + + idx_range_rep (octave_idx_type start, octave_idx_type len, + octave_idx_type step, direct) + : idx_base_rep (), m_start (start), m_len (len), m_step (step) { } + + // Zero-based constructor for index range starting at `start` (inclusive) + // and ending at `limit` (exclusive) in steps of `step`. + idx_range_rep (octave_idx_type start, octave_idx_type limit, + octave_idx_type step); + + OCTAVE_API idx_range_rep (const range<double>&); + + // No copying! + + idx_range_rep (const idx_range_rep& idx) = delete; + + idx_range_rep& operator = (const idx_range_rep& idx) = delete; + + octave_idx_type xelem (octave_idx_type i) const + { return m_start + i * m_step; } + + octave_idx_type checkelem (octave_idx_type i) const; + + octave_idx_type length (octave_idx_type) const { return m_len; } + + octave_idx_type extent (octave_idx_type n) const { - class_invalid = -1, - class_colon = 0, - class_range, - class_scalar, - class_vector, - class_mask - }; + return m_len ? std::max (n, m_start + 1 + (m_step < 0 ? 0 : m_step * (m_len - 1))) : n; + } + + idx_class_type idx_class (void) const { return class_range; } + + OCTAVE_API idx_base_rep * sort_uniq_clone (bool uniq = false); + + OCTAVE_API idx_base_rep * sort_idx (Array<octave_idx_type>&); + + bool is_colon_equiv (octave_idx_type n) const + { return m_start == 0 && m_step == 1 && m_len == n; } - template <typename T, typename D> friend class std::unique_ptr; + dim_vector orig_dimensions (void) const + { return dim_vector (1, m_len); } + + octave_idx_type get_start (void) const { return m_start; } + + octave_idx_type get_step (void) const { return m_step; } + + OCTAVE_API std::ostream& print (std::ostream& os) const; + + OCTAVE_API range<double> unconvert (void) const; + + OCTAVE_API Array<octave_idx_type> as_array (void); private: - class OCTAVE_API idx_base_rep - { - public: - - idx_base_rep (void) : m_count (1) { } - - // No copying! - - idx_base_rep (const idx_base_rep&) = delete; - - idx_base_rep& operator = (const idx_base_rep&) = delete; - - virtual ~idx_base_rep (void) = default; - - // Non-range-checking element query. - virtual octave_idx_type xelem (octave_idx_type i) const = 0; - - // Range-checking element query. - virtual octave_idx_type checkelem (octave_idx_type i) const = 0; - - // Length of the index vector. - virtual octave_idx_type length (octave_idx_type n) const = 0; - - // The maximum index + 1. The actual dimension is passed in. - virtual octave_idx_type extent (octave_idx_type n) const = 0; - - // Index class. - virtual idx_class_type idx_class (void) const { return class_invalid; } - - // Sorts, maybe uniqifies, and returns a clone object pointer. - virtual idx_base_rep * sort_uniq_clone (bool uniq = false) = 0; - // Sorts, and returns a sorting permutation (aka Array::sort). - virtual idx_base_rep * sort_idx (Array<octave_idx_type>&) = 0; - - // Checks whether the index is colon or a range equivalent to colon. - virtual bool is_colon_equiv (octave_idx_type) const { return false; } - - // The original dimensions of object (used when subscribing by matrices). - virtual dim_vector orig_dimensions (void) const { return dim_vector (); } - - // i/o - virtual std::ostream& print (std::ostream& os) const = 0; - - virtual Array<octave_idx_type> as_array (void); + octave_idx_type m_start, m_len, m_step; + }; - refcount<octave_idx_type> m_count; - }; - - // The magic colon index. - class OCTAVE_API idx_colon_rep : public idx_base_rep - { - public: - - idx_colon_rep (void) = default; - - OCTAVE_API idx_colon_rep (char c); - - // No copying! - - idx_colon_rep (const idx_colon_rep& idx) = delete; - - idx_colon_rep& operator = (const idx_colon_rep& idx) = delete; - - octave_idx_type xelem (octave_idx_type i) const { return i; } - - OCTAVE_API octave_idx_type checkelem (octave_idx_type i) const; + // The integer scalar index. + class OCTAVE_API idx_scalar_rep : public idx_base_rep + { + public: - octave_idx_type length (octave_idx_type n) const { return n; } - - octave_idx_type extent (octave_idx_type n) const { return n; } - - idx_class_type idx_class (void) const { return class_colon; } - - idx_base_rep * sort_uniq_clone (bool = false) - { m_count++; return this; } - - OCTAVE_NORETURN idx_base_rep * sort_idx (Array<octave_idx_type>&); + idx_scalar_rep (void) = delete; - bool is_colon_equiv (octave_idx_type) const { return true; } - - OCTAVE_API std::ostream& print (std::ostream& os) const; - }; + idx_scalar_rep (octave_idx_type i, direct) : idx_base_rep (), m_data (i) { } - // To distinguish the "direct" constructors that blindly trust the data. - enum direct { DIRECT }; - - // The integer range index. - class OCTAVE_API idx_range_rep : public idx_base_rep - { - public: + // No copying! - idx_range_rep (void) = delete; - - idx_range_rep (octave_idx_type start, octave_idx_type len, - octave_idx_type step, direct) - : idx_base_rep (), m_start (start), m_len (len), m_step (step) { } - - // Zero-based constructor for index range starting at `start` (inclusive) - // and ending at `limit` (exclusive) in steps of `step`. - idx_range_rep (octave_idx_type start, octave_idx_type limit, - octave_idx_type step); - - OCTAVE_API idx_range_rep (const range<double>&); - - // No copying! - - idx_range_rep (const idx_range_rep& idx) = delete; - - idx_range_rep& operator = (const idx_range_rep& idx) = delete; - - octave_idx_type xelem (octave_idx_type i) const - { return m_start + i * m_step; } + idx_scalar_rep (const idx_scalar_rep& idx) = delete; - octave_idx_type checkelem (octave_idx_type i) const; - - octave_idx_type length (octave_idx_type) const { return m_len; } - - octave_idx_type extent (octave_idx_type n) const - { - return m_len ? std::max (n, m_start + 1 + (m_step < 0 ? 0 : m_step * (m_len - 1))) : n; - } - - idx_class_type idx_class (void) const { return class_range; } + idx_scalar_rep& operator = (const idx_scalar_rep& idx) = delete; - OCTAVE_API idx_base_rep * sort_uniq_clone (bool uniq = false); - - OCTAVE_API idx_base_rep * sort_idx (Array<octave_idx_type>&); - - bool is_colon_equiv (octave_idx_type n) const - { return m_start == 0 && m_step == 1 && m_len == n; } - - dim_vector orig_dimensions (void) const - { return dim_vector (1, m_len); } - - octave_idx_type get_start (void) const { return m_start; } + // Zero-based constructor. + OCTAVE_API idx_scalar_rep (octave_idx_type i); - octave_idx_type get_step (void) const { return m_step; } - - OCTAVE_API std::ostream& print (std::ostream& os) const; - - OCTAVE_API range<double> unconvert (void) const; - - OCTAVE_API Array<octave_idx_type> as_array (void); - - private: - - octave_idx_type m_start, m_len, m_step; - }; - - // The integer scalar index. - class OCTAVE_API idx_scalar_rep : public idx_base_rep - { - public: - - idx_scalar_rep (void) = delete; - - idx_scalar_rep (octave_idx_type i, direct) : idx_base_rep (), m_data (i) { } - - // No copying! + template <typename T> + idx_scalar_rep (T x); - idx_scalar_rep (const idx_scalar_rep& idx) = delete; - - idx_scalar_rep& operator = (const idx_scalar_rep& idx) = delete; - - // Zero-based constructor. - OCTAVE_API idx_scalar_rep (octave_idx_type i); - - template <typename T> - idx_scalar_rep (T x); - - octave_idx_type xelem (octave_idx_type) const { return m_data; } + octave_idx_type xelem (octave_idx_type) const { return m_data; } - OCTAVE_API octave_idx_type checkelem (octave_idx_type i) const; - - octave_idx_type length (octave_idx_type) const { return 1; } + OCTAVE_API octave_idx_type checkelem (octave_idx_type i) const; - octave_idx_type extent (octave_idx_type n) const - { return std::max (n, m_data + 1); } - - idx_class_type idx_class (void) const { return class_scalar; } - - idx_base_rep * sort_uniq_clone (bool = false) - { m_count++; return this; } + octave_idx_type length (octave_idx_type) const { return 1; } - OCTAVE_API idx_base_rep * sort_idx (Array<octave_idx_type>&); - - bool is_colon_equiv (octave_idx_type n) const - { return n == 1 && m_data == 0; } - - dim_vector orig_dimensions (void) const { return dim_vector (1, 1); } - - octave_idx_type get_data (void) const { return m_data; } - - OCTAVE_API std::ostream& print (std::ostream& os) const; - - OCTAVE_API double unconvert (void) const; - - OCTAVE_API Array<octave_idx_type> as_array (void); - - private: - - octave_idx_type m_data; - }; + octave_idx_type extent (octave_idx_type n) const + { return std::max (n, m_data + 1); } - // The integer vector index. - class OCTAVE_API idx_vector_rep : public idx_base_rep - { - public: - - idx_vector_rep (void) - : m_data (nullptr), m_len (0), m_ext (0), m_aowner (nullptr), m_orig_dims () { } - - // Direct constructor. - idx_vector_rep (octave_idx_type *data, octave_idx_type len, - octave_idx_type ext, const dim_vector& od, direct) - : idx_base_rep (), m_data (data), m_len (len), m_ext (ext), - m_aowner (nullptr), m_orig_dims (od) - { } - - // Zero-based constructor. - OCTAVE_API idx_vector_rep (const Array<octave_idx_type>& inda); - - OCTAVE_API idx_vector_rep (const Array<octave_idx_type>& inda, - octave_idx_type ext, direct); - - template <typename T> - idx_vector_rep (const Array<T>&); + idx_class_type idx_class (void) const { return class_scalar; } - OCTAVE_API idx_vector_rep (bool); - - OCTAVE_API idx_vector_rep (const Array<bool>&, octave_idx_type = -1); - - OCTAVE_API idx_vector_rep (const Sparse<bool>&); - - // No copying! - - idx_vector_rep (const idx_vector_rep& idx) = delete; + idx_base_rep * sort_uniq_clone (bool = false) + { m_count++; return this; } - idx_vector_rep& operator = (const idx_vector_rep& idx) = delete; - - ~idx_vector_rep (void); - - octave_idx_type xelem (octave_idx_type i) const { return m_data[i]; } - - OCTAVE_API octave_idx_type checkelem (octave_idx_type i) const; - - octave_idx_type length (octave_idx_type) const { return m_len; } + OCTAVE_API idx_base_rep * sort_idx (Array<octave_idx_type>&); - octave_idx_type extent (octave_idx_type n) const - { return std::max (n, m_ext); } - - idx_class_type idx_class (void) const { return class_vector; } - - idx_base_rep * sort_uniq_clone (bool uniq = false); - - OCTAVE_API idx_base_rep * sort_idx (Array<octave_idx_type>&); - - dim_vector orig_dimensions (void) const { return m_orig_dims; } + bool is_colon_equiv (octave_idx_type n) const + { return n == 1 && m_data == 0; } - const octave_idx_type * get_data (void) const { return m_data; } - - OCTAVE_API std::ostream& print (std::ostream& os) const; - - OCTAVE_API Array<double> unconvert (void) const; - - OCTAVE_API Array<octave_idx_type> as_array (void); - - private: - - const octave_idx_type *m_data; - octave_idx_type m_len; - octave_idx_type m_ext; + dim_vector orig_dimensions (void) const { return dim_vector (1, 1); } - // This is a trick to allow user-given zero-based arrays to be used - // as indices without copying. If the following pointer is nonzero, - // we do not own the data, but rather have an Array<octave_idx_type> - // object that provides us the data. Note that we need a pointer - // because we deferred the Array<T> declaration and we do not want - // it yet to be defined. - - Array<octave_idx_type> *m_aowner; + octave_idx_type get_data (void) const { return m_data; } - dim_vector m_orig_dims; - }; - - // The logical mask index. - class OCTAVE_API idx_mask_rep : public idx_base_rep - { - public: - - idx_mask_rep (void) = delete; + OCTAVE_API std::ostream& print (std::ostream& os) const; - // Direct constructor. - idx_mask_rep (bool *data, octave_idx_type len, - octave_idx_type ext, const dim_vector& od, direct) - : idx_base_rep (), m_data (data), m_len (len), m_ext (ext), - m_lsti (-1), m_lste (-1), m_aowner (nullptr), m_orig_dims (od) - { } - - OCTAVE_API idx_mask_rep (bool); - - OCTAVE_API idx_mask_rep (const Array<bool>&, octave_idx_type = -1); - - // No copying! + OCTAVE_API double unconvert (void) const; - idx_mask_rep (const idx_mask_rep& idx) = delete; - - idx_mask_rep& operator = (const idx_mask_rep& idx) = delete; - - OCTAVE_API ~idx_mask_rep (void); - - octave_idx_type xelem (octave_idx_type i) const; - - octave_idx_type checkelem (octave_idx_type i) const; - - octave_idx_type length (octave_idx_type) const { return m_len; } - - octave_idx_type extent (octave_idx_type n) const - { return std::max (n, m_ext); } + OCTAVE_API Array<octave_idx_type> as_array (void); - idx_class_type idx_class (void) const { return class_mask; } - - idx_base_rep * sort_uniq_clone (bool = false) - { m_count++; return this; } - - OCTAVE_API idx_base_rep * sort_idx (Array<octave_idx_type>&); - - dim_vector orig_dimensions (void) const { return m_orig_dims; } - - bool is_colon_equiv (octave_idx_type n) const - { return m_len == n && m_ext == n; } - - const bool * get_data (void) const { return m_data; } - - OCTAVE_API std::ostream& print (std::ostream& os) const; - - OCTAVE_API Array<bool> unconvert (void) const; - - OCTAVE_API Array<octave_idx_type> as_array (void); - - private: + private: - const bool *m_data; - octave_idx_type m_len; - octave_idx_type m_ext; - - // FIXME: I'm not sure if this is a good design. Maybe it would be - // better to employ some sort of generalized iteration scheme. - mutable octave_idx_type m_lsti; - mutable octave_idx_type m_lste; + octave_idx_type m_data; + }; - // This is a trick to allow user-given mask arrays to be used as - // indices without copying. If the following pointer is nonzero, we - // do not own the data, but rather have an Array<bool> object that - // provides us the data. Note that we need a pointer because we - // deferred the Array<T> declaration and we do not want it yet to be - // defined. - - Array<bool> *m_aowner; - - dim_vector m_orig_dims; - }; - - idx_vector (idx_base_rep *r) : m_rep (r) { } - - // The shared empty vector representation (for fast default - // constructor). - static OCTAVE_API idx_vector_rep * nil_rep (void); - + // The integer vector index. + class OCTAVE_API idx_vector_rep : public idx_base_rep + { public: - // Fast empty constructor. - idx_vector (void) : m_rep (nil_rep ()) { m_rep->m_count++; } + idx_vector_rep (void) + : m_data (nullptr), m_len (0), m_ext (0), m_aowner (nullptr), m_orig_dims () { } + + // Direct constructor. + idx_vector_rep (octave_idx_type *data, octave_idx_type len, + octave_idx_type ext, const dim_vector& od, direct) + : idx_base_rep (), m_data (data), m_len (len), m_ext (ext), + m_aowner (nullptr), m_orig_dims (od) + { } + + // Zero-based constructor. + OCTAVE_API idx_vector_rep (const Array<octave_idx_type>& inda); + + OCTAVE_API idx_vector_rep (const Array<octave_idx_type>& inda, + octave_idx_type ext, direct); + + template <typename T> + idx_vector_rep (const Array<T>&); + + OCTAVE_API idx_vector_rep (bool); + + OCTAVE_API idx_vector_rep (const Array<bool>&, octave_idx_type = -1); + + OCTAVE_API idx_vector_rep (const Sparse<bool>&); + + // No copying! + + idx_vector_rep (const idx_vector_rep& idx) = delete; + + idx_vector_rep& operator = (const idx_vector_rep& idx) = delete; + + ~idx_vector_rep (void); + + octave_idx_type xelem (octave_idx_type i) const { return m_data[i]; } + + OCTAVE_API octave_idx_type checkelem (octave_idx_type i) const; + + octave_idx_type length (octave_idx_type) const { return m_len; } + + octave_idx_type extent (octave_idx_type n) const + { return std::max (n, m_ext); } + + idx_class_type idx_class (void) const { return class_vector; } + + idx_base_rep * sort_uniq_clone (bool uniq = false); + + OCTAVE_API idx_base_rep * sort_idx (Array<octave_idx_type>&); + + dim_vector orig_dimensions (void) const { return m_orig_dims; } + + const octave_idx_type * get_data (void) const { return m_data; } + + OCTAVE_API std::ostream& print (std::ostream& os) const; + + OCTAVE_API Array<double> unconvert (void) const; + + OCTAVE_API Array<octave_idx_type> as_array (void); + + private: + + const octave_idx_type *m_data; + octave_idx_type m_len; + octave_idx_type m_ext; + + // This is a trick to allow user-given zero-based arrays to be used + // as indices without copying. If the following pointer is nonzero, + // we do not own the data, but rather have an Array<octave_idx_type> + // object that provides us the data. Note that we need a pointer + // because we deferred the Array<T> declaration and we do not want + // it yet to be defined. + + Array<octave_idx_type> *m_aowner; + + dim_vector m_orig_dims; + }; + + // The logical mask index. + class OCTAVE_API idx_mask_rep : public idx_base_rep + { + public: + + idx_mask_rep (void) = delete; - // Zero-based constructors (for use from C++). - idx_vector (octave_idx_type i) : m_rep (new idx_scalar_rep (i)) { } + // Direct constructor. + idx_mask_rep (bool *data, octave_idx_type len, + octave_idx_type ext, const dim_vector& od, direct) + : idx_base_rep (), m_data (data), m_len (len), m_ext (ext), + m_lsti (-1), m_lste (-1), m_aowner (nullptr), m_orig_dims (od) + { } + + OCTAVE_API idx_mask_rep (bool); + + OCTAVE_API idx_mask_rep (const Array<bool>&, octave_idx_type = -1); + + // No copying! + + idx_mask_rep (const idx_mask_rep& idx) = delete; + + idx_mask_rep& operator = (const idx_mask_rep& idx) = delete; + + OCTAVE_API ~idx_mask_rep (void); + + octave_idx_type xelem (octave_idx_type i) const; + + octave_idx_type checkelem (octave_idx_type i) const; + + octave_idx_type length (octave_idx_type) const { return m_len; } + + octave_idx_type extent (octave_idx_type n) const + { return std::max (n, m_ext); } + + idx_class_type idx_class (void) const { return class_mask; } + + idx_base_rep * sort_uniq_clone (bool = false) + { m_count++; return this; } + + OCTAVE_API idx_base_rep * sort_idx (Array<octave_idx_type>&); + + dim_vector orig_dimensions (void) const { return m_orig_dims; } + + bool is_colon_equiv (octave_idx_type n) const + { return m_len == n && m_ext == n; } + + const bool * get_data (void) const { return m_data; } + + OCTAVE_API std::ostream& print (std::ostream& os) const; + + OCTAVE_API Array<bool> unconvert (void) const; + + OCTAVE_API Array<octave_idx_type> as_array (void); + + private: + + const bool *m_data; + octave_idx_type m_len; + octave_idx_type m_ext; + + // FIXME: I'm not sure if this is a good design. Maybe it would be + // better to employ some sort of generalized iteration scheme. + mutable octave_idx_type m_lsti; + mutable octave_idx_type m_lste; + + // This is a trick to allow user-given mask arrays to be used as + // indices without copying. If the following pointer is nonzero, we + // do not own the data, but rather have an Array<bool> object that + // provides us the data. Note that we need a pointer because we + // deferred the Array<T> declaration and we do not want it yet to be + // defined. + + Array<bool> *m_aowner; + + dim_vector m_orig_dims; + }; + + idx_vector (idx_base_rep *r) : m_rep (r) { } + + // The shared empty vector representation (for fast default + // constructor). + static OCTAVE_API idx_vector_rep * nil_rep (void); + +public: + + // Fast empty constructor. + idx_vector (void) : m_rep (nil_rep ()) { m_rep->m_count++; } + + // Zero-based constructors (for use from C++). + idx_vector (octave_idx_type i) : m_rep (new idx_scalar_rep (i)) { } #if OCTAVE_SIZEOF_INT != OCTAVE_SIZEOF_IDX_TYPE - idx_vector (int i) - : m_rep (new idx_scalar_rep (static_cast<octave_idx_type> (i))) { } + idx_vector (int i) + : m_rep (new idx_scalar_rep (static_cast<octave_idx_type> (i))) { } #endif #if (OCTAVE_SIZEOF_F77_INT_TYPE != OCTAVE_SIZEOF_IDX_TYPE \ && OCTAVE_SIZEOF_F77_INT_TYPE != OCTAVE_SIZEOF_INT) - idx_vector (octave_f77_int_type i) - : m_rep (new idx_scalar_rep (static_cast<octave_idx_type> (i))) { } + idx_vector (octave_f77_int_type i) + : m_rep (new idx_scalar_rep (static_cast<octave_idx_type> (i))) { } #endif - idx_vector (octave_idx_type start, octave_idx_type limit, - octave_idx_type step = 1) - : m_rep (new idx_range_rep (start, limit, step)) { } + idx_vector (octave_idx_type start, octave_idx_type limit, + octave_idx_type step = 1) + : m_rep (new idx_range_rep (start, limit, step)) { } - static idx_vector - make_range (octave_idx_type start, octave_idx_type step, - octave_idx_type len) - { - return idx_vector (new idx_range_rep (start, len, step, DIRECT)); - } + static idx_vector + make_range (octave_idx_type start, octave_idx_type step, + octave_idx_type len) + { + return idx_vector (new idx_range_rep (start, len, step, DIRECT)); + } - idx_vector (const Array<octave_idx_type>& inda) - : m_rep (new idx_vector_rep (inda)) { } + idx_vector (const Array<octave_idx_type>& inda) + : m_rep (new idx_vector_rep (inda)) { } - // Directly pass extent, no checking. - idx_vector (const Array<octave_idx_type>& inda, octave_idx_type ext) - : m_rep (new idx_vector_rep (inda, ext, DIRECT)) { } + // Directly pass extent, no checking. + idx_vector (const Array<octave_idx_type>& inda, octave_idx_type ext) + : m_rep (new idx_vector_rep (inda, ext, DIRECT)) { } - // Colon is best constructed by simply copying (or referencing) this member. - static const idx_vector colon; + // Colon is best constructed by simply copying (or referencing) this member. + static const idx_vector colon; - // or passing ':' here - idx_vector (char c) : m_rep (new idx_colon_rep (c)) { } + // or passing ':' here + idx_vector (char c) : m_rep (new idx_colon_rep (c)) { } - // Conversion constructors (used by interpreter). + // Conversion constructors (used by interpreter). - template <typename T> - idx_vector (octave_int<T> x) : m_rep (new idx_scalar_rep (x)) { } + template <typename T> + idx_vector (octave_int<T> x) : m_rep (new idx_scalar_rep (x)) { } - idx_vector (double x) : m_rep (new idx_scalar_rep (x)) { } + idx_vector (double x) : m_rep (new idx_scalar_rep (x)) { } - idx_vector (float x) : m_rep (new idx_scalar_rep (x)) { } + idx_vector (float x) : m_rep (new idx_scalar_rep (x)) { } - // A scalar bool does not necessarily map to scalar index. - idx_vector (bool x) : m_rep (new idx_mask_rep (x)) { } + // A scalar bool does not necessarily map to scalar index. + idx_vector (bool x) : m_rep (new idx_mask_rep (x)) { } - template <typename T> - idx_vector (const Array<octave_int<T>>& nda) - : m_rep (new idx_vector_rep (nda)) { } + template <typename T> + idx_vector (const Array<octave_int<T>>& nda) + : m_rep (new idx_vector_rep (nda)) { } - idx_vector (const Array<double>& nda) : m_rep (new idx_vector_rep (nda)) { } + idx_vector (const Array<double>& nda) : m_rep (new idx_vector_rep (nda)) { } - idx_vector (const Array<float>& nda) : m_rep (new idx_vector_rep (nda)) { } + idx_vector (const Array<float>& nda) : m_rep (new idx_vector_rep (nda)) { } - OCTAVE_API idx_vector (const Array<bool>& nda); + OCTAVE_API idx_vector (const Array<bool>& nda); - idx_vector (const range<double>& r) : m_rep (new idx_range_rep (r)) { } + idx_vector (const range<double>& r) : m_rep (new idx_range_rep (r)) { } - idx_vector (const Sparse<bool>& nda) : m_rep (new idx_vector_rep (nda)) { } + idx_vector (const Sparse<bool>& nda) : m_rep (new idx_vector_rep (nda)) { } - idx_vector (const idx_vector& a) : m_rep (a.m_rep) { m_rep->m_count++; } + idx_vector (const idx_vector& a) : m_rep (a.m_rep) { m_rep->m_count++; } - ~idx_vector (void) - { - if (--m_rep->m_count == 0 && m_rep != nil_rep ()) - delete m_rep; - } + ~idx_vector (void) + { + if (--m_rep->m_count == 0 && m_rep != nil_rep ()) + delete m_rep; + } - idx_vector& operator = (const idx_vector& a) - { - if (this != &a) - { - if (--m_rep->m_count == 0 && m_rep != nil_rep ()) - delete m_rep; + idx_vector& operator = (const idx_vector& a) + { + if (this != &a) + { + if (--m_rep->m_count == 0 && m_rep != nil_rep ()) + delete m_rep; - m_rep = a.m_rep; - m_rep->m_count++; - } - return *this; - } + m_rep = a.m_rep; + m_rep->m_count++; + } + return *this; + } - idx_class_type idx_class (void) const { return m_rep->idx_class (); } + idx_class_type idx_class (void) const { return m_rep->idx_class (); } - octave_idx_type length (octave_idx_type n = 0) const - { return m_rep->length (n); } + octave_idx_type length (octave_idx_type n = 0) const + { return m_rep->length (n); } - octave_idx_type extent (octave_idx_type n) const - { return m_rep->extent (n); } + octave_idx_type extent (octave_idx_type n) const + { return m_rep->extent (n); } - octave_idx_type xelem (octave_idx_type n) const - { return m_rep->xelem (n); } + octave_idx_type xelem (octave_idx_type n) const + { return m_rep->xelem (n); } - octave_idx_type checkelem (octave_idx_type n) const - { return m_rep->xelem (n); } + octave_idx_type checkelem (octave_idx_type n) const + { return m_rep->xelem (n); } - octave_idx_type operator () (octave_idx_type n) const - { return m_rep->xelem (n); } + octave_idx_type operator () (octave_idx_type n) const + { return m_rep->xelem (n); } - // FIXME: idx_vector objects are either created successfully or an - // error is thrown, so this method no longer makes sense. - operator bool (void) const { return true; } + // FIXME: idx_vector objects are either created successfully or an + // error is thrown, so this method no longer makes sense. + operator bool (void) const { return true; } - bool is_colon (void) const - { return m_rep->idx_class () == class_colon; } + bool is_colon (void) const + { return m_rep->idx_class () == class_colon; } - bool is_scalar (void) const - { return m_rep->idx_class () == class_scalar; } + bool is_scalar (void) const + { return m_rep->idx_class () == class_scalar; } - bool is_range (void) const - { return m_rep->idx_class () == class_range; } + bool is_range (void) const + { return m_rep->idx_class () == class_range; } - bool is_colon_equiv (octave_idx_type n) const - { return m_rep->is_colon_equiv (n); } + bool is_colon_equiv (octave_idx_type n) const + { return m_rep->is_colon_equiv (n); } - idx_vector sorted (bool uniq = false) const - { return idx_vector (m_rep->sort_uniq_clone (uniq)); } + idx_vector sorted (bool uniq = false) const + { return idx_vector (m_rep->sort_uniq_clone (uniq)); } - idx_vector sorted (Array<octave_idx_type>& sidx) const - { return idx_vector (m_rep->sort_idx (sidx)); } + idx_vector sorted (Array<octave_idx_type>& sidx) const + { return idx_vector (m_rep->sort_idx (sidx)); } - dim_vector orig_dimensions (void) const { return m_rep->orig_dimensions (); } + dim_vector orig_dimensions (void) const { return m_rep->orig_dimensions (); } - octave_idx_type orig_rows (void) const - { return orig_dimensions () (0); } + octave_idx_type orig_rows (void) const + { return orig_dimensions () (0); } - octave_idx_type orig_columns (void) const - { return orig_dimensions () (1); } + octave_idx_type orig_columns (void) const + { return orig_dimensions () (1); } - int orig_empty (void) const - { return (! is_colon () && orig_dimensions ().any_zero ()); } + int orig_empty (void) const + { return (! is_colon () && orig_dimensions ().any_zero ()); } - // i/o + // i/o - std::ostream& print (std::ostream& os) const { return m_rep->print (os); } + std::ostream& print (std::ostream& os) const { return m_rep->print (os); } - friend std::ostream& operator << (std::ostream& os, const idx_vector& a) - { return a.print (os); } + friend std::ostream& operator << (std::ostream& os, const idx_vector& a) + { return a.print (os); } - // Slice with specializations. No checking of bounds! - // - // This is equivalent to the following loop (but much faster): - // - // for (octave_idx_type i = 0; i < idx->length (n); i++) - // dest[i] = src[idx(i)]; - // return i; - // - template <typename T> - octave_idx_type - index (const T *src, octave_idx_type n, T *dest) const - { - octave_idx_type len = m_rep->length (n); + // Slice with specializations. No checking of bounds! + // + // This is equivalent to the following loop (but much faster): + // + // for (octave_idx_type i = 0; i < idx->length (n); i++) + // dest[i] = src[idx(i)]; + // return i; + // + template <typename T> + octave_idx_type + index (const T *src, octave_idx_type n, T *dest) const + { + octave_idx_type len = m_rep->length (n); - switch (m_rep->idx_class ()) - { - case class_colon: - std::copy_n (src, len, dest); - break; + switch (m_rep->idx_class ()) + { + case class_colon: + std::copy_n (src, len, dest); + break; - case class_range: - { - idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep); - octave_idx_type start = r->get_start (); - octave_idx_type step = r->get_step (); - const T *ssrc = src + start; - if (step == 1) - std::copy_n (ssrc, len, dest); - else if (step == -1) - std::reverse_copy (ssrc - len + 1, ssrc + 1, dest); - else if (step == 0) - std::fill_n (dest, len, *ssrc); - else - { - for (octave_idx_type i = 0, j = 0; i < len; i++, j += step) - dest[i] = ssrc[j]; - } - } - break; + case class_range: + { + idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep); + octave_idx_type start = r->get_start (); + octave_idx_type step = r->get_step (); + const T *ssrc = src + start; + if (step == 1) + std::copy_n (ssrc, len, dest); + else if (step == -1) + std::reverse_copy (ssrc - len + 1, ssrc + 1, dest); + else if (step == 0) + std::fill_n (dest, len, *ssrc); + else + { + for (octave_idx_type i = 0, j = 0; i < len; i++, j += step) + dest[i] = ssrc[j]; + } + } + break; - case class_scalar: - { - idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep); - dest[0] = src[r->get_data ()]; - } - break; + case class_scalar: + { + idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep); + dest[0] = src[r->get_data ()]; + } + break; - case class_vector: - { - idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep); - const octave_idx_type *data = r->get_data (); - for (octave_idx_type i = 0; i < len; i++) - dest[i] = src[data[i]]; - } - break; + case class_vector: + { + idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep); + const octave_idx_type *data = r->get_data (); + for (octave_idx_type i = 0; i < len; i++) + dest[i] = src[data[i]]; + } + break; - case class_mask: - { - idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep); - const bool *data = r->get_data (); - octave_idx_type ext = r->extent (0); - for (octave_idx_type i = 0; i < ext; i++) - if (data[i]) *dest++ = src[i]; - } - break; + case class_mask: + { + idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep); + const bool *data = r->get_data (); + octave_idx_type ext = r->extent (0); + for (octave_idx_type i = 0; i < ext; i++) + if (data[i]) *dest++ = src[i]; + } + break; - default: - assert (false); - break; - } + default: + assert (false); + break; + } - return len; - } + return len; + } - // Slice assignment with specializations. No checking of bounds! - // - // This is equivalent to the following loop (but much faster): - // - // for (octave_idx_type i = 0; i < idx->length (n); i++) - // dest[idx(i)] = src[i]; - // return i; - // - template <typename T> - octave_idx_type - assign (const T *src, octave_idx_type n, T *dest) const - { - octave_idx_type len = m_rep->length (n); + // Slice assignment with specializations. No checking of bounds! + // + // This is equivalent to the following loop (but much faster): + // + // for (octave_idx_type i = 0; i < idx->length (n); i++) + // dest[idx(i)] = src[i]; + // return i; + // + template <typename T> + octave_idx_type + assign (const T *src, octave_idx_type n, T *dest) const + { + octave_idx_type len = m_rep->length (n); - switch (m_rep->idx_class ()) - { - case class_colon: - std::copy_n (src, len, dest); - break; + switch (m_rep->idx_class ()) + { + case class_colon: + std::copy_n (src, len, dest); + break; - case class_range: - { - idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep); - octave_idx_type start = r->get_start (); - octave_idx_type step = r->get_step (); - T *sdest = dest + start; - if (step == 1) - std::copy_n (src, len, sdest); - else if (step == -1) - std::reverse_copy (src, src + len, sdest - len + 1); - else - { - for (octave_idx_type i = 0, j = 0; i < len; i++, j += step) - sdest[j] = src[i]; - } - } - break; + case class_range: + { + idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep); + octave_idx_type start = r->get_start (); + octave_idx_type step = r->get_step (); + T *sdest = dest + start; + if (step == 1) + std::copy_n (src, len, sdest); + else if (step == -1) + std::reverse_copy (src, src + len, sdest - len + 1); + else + { + for (octave_idx_type i = 0, j = 0; i < len; i++, j += step) + sdest[j] = src[i]; + } + } + break; - case class_scalar: - { - idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep); - dest[r->get_data ()] = src[0]; - } - break; + case class_scalar: + { + idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep); + dest[r->get_data ()] = src[0]; + } + break; - case class_vector: - { - idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep); - const octave_idx_type *data = r->get_data (); - for (octave_idx_type i = 0; i < len; i++) - dest[data[i]] = src[i]; - } - break; + case class_vector: + { + idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep); + const octave_idx_type *data = r->get_data (); + for (octave_idx_type i = 0; i < len; i++) + dest[data[i]] = src[i]; + } + break; - case class_mask: - { - idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep); - const bool *data = r->get_data (); - octave_idx_type ext = r->extent (0); - for (octave_idx_type i = 0; i < ext; i++) - if (data[i]) dest[i] = *src++; - } - break; + case class_mask: + { + idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep); + const bool *data = r->get_data (); + octave_idx_type ext = r->extent (0); + for (octave_idx_type i = 0; i < ext; i++) + if (data[i]) dest[i] = *src++; + } + break; - default: - assert (false); - break; - } + default: + assert (false); + break; + } - return len; - } + return len; + } - // Slice fill with specializations. No checking of bounds! - // - // This is equivalent to the following loop (but much faster): - // - // for (octave_idx_type i = 0; i < idx->length (n); i++) - // dest[idx(i)] = val; - // return i; - // - template <typename T> - octave_idx_type - fill (const T& val, octave_idx_type n, T *dest) const - { - octave_idx_type len = m_rep->length (n); + // Slice fill with specializations. No checking of bounds! + // + // This is equivalent to the following loop (but much faster): + // + // for (octave_idx_type i = 0; i < idx->length (n); i++) + // dest[idx(i)] = val; + // return i; + // + template <typename T> + octave_idx_type + fill (const T& val, octave_idx_type n, T *dest) const + { + octave_idx_type len = m_rep->length (n); - switch (m_rep->idx_class ()) - { - case class_colon: - std::fill_n (dest, len, val); - break; + switch (m_rep->idx_class ()) + { + case class_colon: + std::fill_n (dest, len, val); + break; - case class_range: - { - idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep); - octave_idx_type start = r->get_start (); - octave_idx_type step = r->get_step (); - T *sdest = dest + start; - if (step == 1) - std::fill_n (sdest, len, val); - else if (step == -1) - std::fill (sdest - len + 1, sdest + 1, val); - else - { - for (octave_idx_type i = 0, j = 0; i < len; i++, j += step) - sdest[j] = val; - } - } - break; + case class_range: + { + idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep); + octave_idx_type start = r->get_start (); + octave_idx_type step = r->get_step (); + T *sdest = dest + start; + if (step == 1) + std::fill_n (sdest, len, val); + else if (step == -1) + std::fill (sdest - len + 1, sdest + 1, val); + else + { + for (octave_idx_type i = 0, j = 0; i < len; i++, j += step) + sdest[j] = val; + } + } + break; - case class_scalar: - { - idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep); - dest[r->get_data ()] = val; - } - break; + case class_scalar: + { + idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep); + dest[r->get_data ()] = val; + } + break; - case class_vector: - { - idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep); - const octave_idx_type *data = r->get_data (); - for (octave_idx_type i = 0; i < len; i++) - dest[data[i]] = val; - } - break; + case class_vector: + { + idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep); + const octave_idx_type *data = r->get_data (); + for (octave_idx_type i = 0; i < len; i++) + dest[data[i]] = val; + } + break; - case class_mask: - { - idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep); - const bool *data = r->get_data (); - octave_idx_type ext = r->extent (0); - for (octave_idx_type i = 0; i < ext; i++) - if (data[i]) dest[i] = val; - } - break; + case class_mask: + { + idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep); + const bool *data = r->get_data (); + octave_idx_type ext = r->extent (0); + for (octave_idx_type i = 0; i < ext; i++) + if (data[i]) dest[i] = val; + } + break; - default: - assert (false); - break; - } + default: + assert (false); + break; + } - return len; - } + return len; + } - // Generic non-breakable indexed loop. The loop body should be - // encapsulated in a single functor body. This is equivalent to the - // following loop (but faster, at least for simple inlined bodies): - // - // for (octave_idx_type i = 0; i < idx->length (n); i++) body (idx(i)); + // Generic non-breakable indexed loop. The loop body should be + // encapsulated in a single functor body. This is equivalent to the + // following loop (but faster, at least for simple inlined bodies): + // + // for (octave_idx_type i = 0; i < idx->length (n); i++) body (idx(i)); - template <typename Functor> - void - loop (octave_idx_type n, Functor body) const - { - octave_idx_type len = m_rep->length (n); + template <typename Functor> + void + loop (octave_idx_type n, Functor body) const + { + octave_idx_type len = m_rep->length (n); - switch (m_rep->idx_class ()) + switch (m_rep->idx_class ()) + { + case class_colon: + for (octave_idx_type i = 0; i < len; i++) body (i); + break; + + case class_range: { - case class_colon: - for (octave_idx_type i = 0; i < len; i++) body (i); - break; - - case class_range: - { - idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep); - octave_idx_type start = r->get_start (); - octave_idx_type step = r->get_step (); - octave_idx_type i, j; - if (step == 1) - for (i = start, j = start + len; i < j; i++) body (i); - else if (step == -1) - for (i = start, j = start - len; i > j; i--) body (i); - else - for (i = 0, j = start; i < len; i++, j += step) body (j); - } - break; + idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep); + octave_idx_type start = r->get_start (); + octave_idx_type step = r->get_step (); + octave_idx_type i, j; + if (step == 1) + for (i = start, j = start + len; i < j; i++) body (i); + else if (step == -1) + for (i = start, j = start - len; i > j; i--) body (i); + else + for (i = 0, j = start; i < len; i++, j += step) body (j); + } + break; - case class_scalar: - { - idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep); - body (r->get_data ()); - } - break; + case class_scalar: + { + idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep); + body (r->get_data ()); + } + break; - case class_vector: - { - idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep); - const octave_idx_type *data = r->get_data (); - for (octave_idx_type i = 0; i < len; i++) body (data[i]); - } - break; + case class_vector: + { + idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep); + const octave_idx_type *data = r->get_data (); + for (octave_idx_type i = 0; i < len; i++) body (data[i]); + } + break; - case class_mask: - { - idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep); - const bool *data = r->get_data (); - octave_idx_type ext = r->extent (0); - for (octave_idx_type i = 0; i < ext; i++) - if (data[i]) body (i); - } - break; + case class_mask: + { + idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep); + const bool *data = r->get_data (); + octave_idx_type ext = r->extent (0); + for (octave_idx_type i = 0; i < ext; i++) + if (data[i]) body (i); + } + break; - default: - assert (false); - break; - } + default: + assert (false); + break; + } - } + } - // Generic breakable indexed loop. The loop body should be - // encapsulated in a single functor body. This is equivalent to the - // following loop (but faster, at least for simple inlined bodies): - // - // for (octave_idx_type i = 0; i < idx->length (n); i++) - // if (body (idx(i))) break; - // return i; - // + // Generic breakable indexed loop. The loop body should be + // encapsulated in a single functor body. This is equivalent to the + // following loop (but faster, at least for simple inlined bodies): + // + // for (octave_idx_type i = 0; i < idx->length (n); i++) + // if (body (idx(i))) break; + // return i; + // - template <typename Functor> - octave_idx_type - bloop (octave_idx_type n, Functor body) const - { - octave_idx_type len = m_rep->length (n), ret; + template <typename Functor> + octave_idx_type + bloop (octave_idx_type n, Functor body) const + { + octave_idx_type len = m_rep->length (n), ret; - switch (m_rep->idx_class ()) + switch (m_rep->idx_class ()) + { + case class_colon: { - case class_colon: - { - octave_idx_type i; - for (i = 0; i < len && body (i); i++) ; - ret = i; - } - break; + octave_idx_type i; + for (i = 0; i < len && body (i); i++) ; + ret = i; + } + break; - case class_range: - { - idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep); - octave_idx_type start = r->get_start (); - octave_idx_type step = r->get_step (); - octave_idx_type i, j; - if (step == 1) - for (i = start, j = start + len; i < j && body (i); i++) ; - else if (step == -1) - for (i = start, j = start - len; i > j && body (i); i--) ; - else - for (i = 0, j = start; i < len && body (j); i++, j += step) ; - ret = i; - } - break; + case class_range: + { + idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep); + octave_idx_type start = r->get_start (); + octave_idx_type step = r->get_step (); + octave_idx_type i, j; + if (step == 1) + for (i = start, j = start + len; i < j && body (i); i++) ; + else if (step == -1) + for (i = start, j = start - len; i > j && body (i); i--) ; + else + for (i = 0, j = start; i < len && body (j); i++, j += step) ; + ret = i; + } + break; - case class_scalar: - { - idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep); - ret = (body (r->get_data ()) ? 1 : 0); - } - break; + case class_scalar: + { + idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep); + ret = (body (r->get_data ()) ? 1 : 0); + } + break; - case class_vector: - { - idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep); - const octave_idx_type *data = r->get_data (); - octave_idx_type i; - for (i = 0; i < len && body (data[i]); i++) ; - ret = i; - } - break; + case class_vector: + { + idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep); + const octave_idx_type *data = r->get_data (); + octave_idx_type i; + for (i = 0; i < len && body (data[i]); i++) ; + ret = i; + } + break; - case class_mask: - { - idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep); - const bool *data = r->get_data (); - octave_idx_type ext = r->extent (0); - octave_idx_type j = 0; - for (octave_idx_type i = 0; i < ext; i++) - { - if (data[i]) - { - if (body (i)) - break; - else - j++; - } - } + case class_mask: + { + idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep); + const bool *data = r->get_data (); + octave_idx_type ext = r->extent (0); + octave_idx_type j = 0; + for (octave_idx_type i = 0; i < ext; i++) + { + if (data[i]) + { + if (body (i)) + break; + else + j++; + } + } - ret = j; - } - break; - - default: - assert (false); - break; + ret = j; } + break; - return ret; - } + default: + assert (false); + break; + } + + return ret; + } - // Rationale: - // This method is the key to "smart indexing". When indexing cartesian - // arrays, sometimes consecutive index vectors can be reduced into a - // single index. If rows (A) = k and i.maybe_reduce (j) gives k, then - // A(i,j)(:) is equal to A(k)(:). + // Rationale: + // This method is the key to "smart indexing". When indexing cartesian + // arrays, sometimes consecutive index vectors can be reduced into a + // single index. If rows (A) = k and i.maybe_reduce (j) gives k, then + // A(i,j)(:) is equal to A(k)(:). - // If the next index can be reduced, returns true and updates this. - OCTAVE_API bool - maybe_reduce (octave_idx_type n, const idx_vector& j, octave_idx_type nj); - - OCTAVE_API bool - is_cont_range (octave_idx_type n, octave_idx_type& l, - octave_idx_type& u) const; + // If the next index can be reduced, returns true and updates this. + OCTAVE_API bool + maybe_reduce (octave_idx_type n, const idx_vector& j, octave_idx_type nj); - // Returns the increment for ranges and colon, 0 for scalars and empty - // vectors, 1st difference otherwise. - OCTAVE_API octave_idx_type increment (void) const; + OCTAVE_API bool + is_cont_range (octave_idx_type n, octave_idx_type& l, + octave_idx_type& u) const; - OCTAVE_API idx_vector - complement (octave_idx_type n) const; - - OCTAVE_API bool is_permutation (octave_idx_type n) const; + // Returns the increment for ranges and colon, 0 for scalars and empty + // vectors, 1st difference otherwise. + OCTAVE_API octave_idx_type increment (void) const; - // Returns the inverse permutation. If this is not a permutation on 1:n, the - // result is undefined (but no error unless extent () != n). - OCTAVE_API idx_vector inverse_permutation (octave_idx_type n) const; + OCTAVE_API idx_vector + complement (octave_idx_type n) const; + + OCTAVE_API bool is_permutation (octave_idx_type n) const; - // Copies all the indices to a given array. Not allowed for colons. - OCTAVE_API void copy_data (octave_idx_type *data) const; + // Returns the inverse permutation. If this is not a permutation on 1:n, the + // result is undefined (but no error unless extent () != n). + OCTAVE_API idx_vector inverse_permutation (octave_idx_type n) const; - // If the index is a mask, convert it to index vector. - OCTAVE_API idx_vector unmask (void) const; + // Copies all the indices to a given array. Not allowed for colons. + OCTAVE_API void copy_data (octave_idx_type *data) const; - // Unconverts the index to a scalar, Range, double array or a mask. - OCTAVE_API void - unconvert (idx_class_type& iclass, double& scalar, range<double>& range, - Array<double>& array, Array<bool>& mask) const; + // If the index is a mask, convert it to index vector. + OCTAVE_API idx_vector unmask (void) const; - OCTAVE_API Array<octave_idx_type> as_array (void) const; + // Unconverts the index to a scalar, Range, double array or a mask. + OCTAVE_API void + unconvert (idx_class_type& iclass, double& scalar, range<double>& range, + Array<double>& array, Array<bool>& mask) const; - // Raw pointer to index array. This is non-const because it may be - // necessary to mutate the index. - const OCTAVE_API octave_idx_type * raw (void); - - OCTAVE_API bool isvector (void) const; + OCTAVE_API Array<octave_idx_type> as_array (void) const; - // FIXME: these are here for compatibility. They should be removed - // when no longer in use. + // Raw pointer to index array. This is non-const because it may be + // necessary to mutate the index. + const OCTAVE_API octave_idx_type * raw (void); - octave_idx_type elem (octave_idx_type n) const - { return (*this) (n); } + OCTAVE_API bool isvector (void) const; + + // FIXME: these are here for compatibility. They should be removed + // when no longer in use. - bool is_colon_equiv (octave_idx_type n, int) const - { return is_colon_equiv (n); } + octave_idx_type elem (octave_idx_type n) const + { return (*this) (n); } - OCTAVE_API octave_idx_type - freeze (octave_idx_type z_len, const char *tag, bool resize_ok = false); + bool is_colon_equiv (octave_idx_type n, int) const + { return is_colon_equiv (n); } - void sort (bool uniq = false) - { *this = sorted (uniq); } + OCTAVE_API octave_idx_type + freeze (octave_idx_type z_len, const char *tag, bool resize_ok = false); - OCTAVE_API octave_idx_type ones_count (void) const; + void sort (bool uniq = false) + { *this = sorted (uniq); } - octave_idx_type max (void) const { return extent (1) - 1; } + OCTAVE_API octave_idx_type ones_count (void) const; - private: + octave_idx_type max (void) const { return extent (1) - 1; } + +private: - idx_base_rep *m_rep; + idx_base_rep *m_rep; - }; +}; OCTAVE_END_NAMESPACE(octave)