home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / octave-1.1.1p1-bin.lha / include / octave / Array.cc next >
C/C++ Source or Header  |  1996-10-12  |  16KB  |  1,007 lines

  1. // Template array classes                              -*- C++ -*-
  2. /*
  3.  
  4. Copyright (C) 1993, 1994, 1995 John W. Eaton
  5.  
  6. This file is part of Octave.
  7.  
  8. Octave is free software; you can redistribute it and/or modify it
  9. under the terms of the GNU General Public License as published by the
  10. Free Software Foundation; either version 2, or (at your option) any
  11. later version.
  12.  
  13. Octave is distributed in the hope that it will be useful, but WITHOUT
  14. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16. for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with Octave; see the file COPYING.  If not, write to the Free
  20. Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22. */
  23.  
  24. #ifdef HAVE_CONFIG_H
  25. #include "config.h"
  26. #endif
  27.  
  28. #include <assert.h>
  29.  
  30. #include "Array.h"
  31.  
  32. /*
  33.  * The real representation of all arrays.
  34.  */
  35.  
  36. template <class T>
  37. ArrayRep<T>::ArrayRep (T *d, int l)
  38. {
  39.   data = d;
  40.   len = l;
  41. }
  42.  
  43. template <class T>
  44. ArrayRep<T>::ArrayRep (void)
  45. {
  46.   len = 0;
  47.   data = (T *) 0;
  48. }
  49.  
  50. template <class T>
  51. ArrayRep<T>::ArrayRep (int n)
  52. {
  53.   len = n;
  54.   data = new T [len];
  55. }
  56.  
  57. template <class T>
  58. ArrayRep<T>::ArrayRep (const ArrayRep<T>& a)
  59. {
  60.   len = a.len;
  61.   count = a.count;
  62.   data = new T [len];
  63.   for (int i = 0; i < len; i++)
  64.     data[i] = a.data[i];
  65. }
  66.  
  67. template <class T>
  68. ArrayRep<T>::~ArrayRep (void)
  69. {
  70.   delete [] data;
  71.   data = (T *) 0;
  72. }
  73.  
  74. template <class T>
  75. int
  76. ArrayRep<T>::length (void) const
  77. {
  78.   return len;
  79. }
  80.  
  81. template <class T>
  82. T&
  83. ArrayRep<T>::elem (int n)
  84. {
  85.   return data[n];
  86. }
  87.  
  88. template <class T>
  89. T
  90. ArrayRep<T>::elem (int n) const
  91. {
  92.   return data[n];
  93. }
  94.  
  95. /*
  96.  * One dimensional array class.  Handles the reference counting for
  97.  * all the derived classes.
  98.  */
  99.  
  100. template <class T>
  101. Array<T>::Array (T *d, int l)
  102. {
  103.   rep = new ArrayRep<T> (d, l);
  104.   rep->count = 1;
  105. }
  106.  
  107. template <class T>
  108. Array<T>::Array (void)
  109. {
  110.   rep = new ArrayRep<T>;
  111.   rep->count = 1;
  112. }
  113.  
  114. template <class T>
  115. Array<T>::Array (int n)
  116. {
  117.   rep = new ArrayRep<T> (n);
  118.   rep->count = 1;
  119. }
  120.  
  121. template <class T>
  122. Array<T>::Array (int n, const T& val)
  123. {
  124.   rep = new ArrayRep<T> (n);
  125.   rep->count = 1;
  126.   for (int i = 0; i < n; i++)
  127.     rep->data[i] = val;
  128. }
  129.  
  130. template <class T>
  131. Array<T>::Array (const Array<T>& a)
  132. {
  133.   rep = a.rep;
  134.   rep->count++;
  135. }
  136.  
  137. template <class T>
  138. Array<T>::~Array (void)
  139. {
  140.   if (--rep->count <= 0)
  141.     delete rep;
  142. }
  143.  
  144. template <class T>
  145. Array<T>&
  146. Array<T>::operator = (const Array<T>& a)
  147. {
  148.   if (this != &a)
  149.     {
  150.       if (--rep->count <= 0)
  151.     delete rep;
  152.  
  153.       rep = a.rep;
  154.       rep->count++;
  155.     }
  156.  
  157.   return *this;
  158. }
  159.  
  160. template <class T>
  161. int
  162. Array<T>::capacity (void) const
  163. {
  164.   return rep->length ();
  165. }
  166.  
  167. template <class T>
  168. int
  169. Array<T>::length (void) const
  170. {
  171.   return rep->length ();
  172. }
  173.  
  174. template <class T>
  175. T&
  176. Array<T>::elem (int n)
  177. {
  178.   if (rep->count > 1)
  179.     {
  180.       --rep->count;
  181.       rep = new ArrayRep<T> (*rep);
  182.       rep->count = 1;
  183.     }
  184.   return rep->elem (n);
  185. }
  186.  
  187. template <class T>
  188. T&
  189. Array<T>::checkelem (int n)
  190. {
  191.   if (n < 0 || n >= rep->length ())
  192.     {
  193.       (*current_liboctave_error_handler) ("range error");
  194.       static T foo;
  195.       return foo;
  196.     }
  197.   return elem (n);
  198. }
  199.  
  200. template <class T>
  201. T&
  202. Array<T>::operator () (int n)
  203. {
  204.   return checkelem (n);
  205. }
  206.  
  207. template <class T>
  208. T&
  209. Array<T>::xelem (int n)
  210. {
  211.   return rep->elem (n);
  212. }
  213.  
  214. template <class T>
  215. T
  216. Array<T>::elem (int n) const
  217. {
  218.   return rep->elem (n);
  219. }
  220.  
  221. template <class T>
  222. T
  223. Array<T>::checkelem (int n) const
  224. {
  225.   if (n < 0 || n >= rep->length ())
  226.     {
  227.       (*current_liboctave_error_handler) ("range error");
  228.       T foo;
  229.       return foo;
  230.     }
  231.   return elem (n);
  232. }
  233.  
  234. template <class T>
  235. T
  236. Array<T>::operator () (int n) const
  237. {
  238.   return checkelem (n);
  239. }
  240.  
  241. template <class T>
  242. void
  243. Array<T>::resize (int n)
  244. {
  245.   if (n < 0)
  246.     {
  247.       (*current_liboctave_error_handler)
  248.     ("can't resize to negative dimension");
  249.       return;
  250.     }
  251.  
  252.   if (n == length ())
  253.     return;
  254.  
  255.   ArrayRep<T> *old_rep = rep;
  256.   const T *old_data = data ();
  257.   int old_len = length ();
  258.  
  259.   rep = new ArrayRep<T> (n);
  260.   rep->count = 1;
  261.  
  262.   if (old_data && old_len > 0)
  263.     {
  264.       int min_len = old_len < n ? old_len : n;
  265.  
  266.       for (int i = 0; i < min_len; i++)
  267.     xelem (i) = old_data[i];
  268.     }
  269.  
  270.   if (--old_rep->count <= 0)
  271.     delete old_rep;
  272. }
  273.  
  274. template <class T>
  275. void
  276. Array<T>::resize (int n, const T& val)
  277. {
  278.   if (n < 0)
  279.     {
  280.       (*current_liboctave_error_handler)
  281.     ("can't resize to negative dimension");
  282.       return;
  283.     }
  284.  
  285.   if (n == length ())
  286.     return;
  287.  
  288.   ArrayRep<T> *old_rep = rep;
  289.   const T *old_data = data ();
  290.   int old_len = length ();
  291.  
  292.   rep = new ArrayRep<T> (n);
  293.   rep->count = 1;
  294.  
  295.   int min_len = old_len < n ? old_len : n;
  296.  
  297.   if (old_data && old_len > 0)
  298.     {
  299.       for (int i = 0; i < min_len; i++)
  300.     xelem (i) = old_data[i];
  301.     }
  302.  
  303.   for (int i = old_len; i < n; i++)
  304.     xelem (i) = val;
  305.  
  306.   if (--old_rep->count <= 0)
  307.     delete old_rep;
  308. }
  309.  
  310. template <class T>
  311. const T *
  312. Array<T>::data (void) const
  313. {
  314.   return rep->data;
  315. }
  316.  
  317. template <class T>
  318. T *
  319. Array<T>::fortran_vec (void)
  320. {
  321.   if (rep->count > 1)
  322.     {
  323.       --rep->count;
  324.       rep = new ArrayRep<T> (*rep);
  325.       rep->count = 1;
  326.     }
  327.   return rep->data;
  328. }
  329.  
  330. /*
  331.  * Two dimensional array class.
  332.  */
  333.  
  334. template <class T>
  335. Array2<T>::Array2 (T *d, int n, int m) : Array<T> (d, n*m)
  336. {
  337.   d1 = n;
  338.   d2 = m;
  339. }
  340.  
  341. template <class T>
  342. Array2<T>::Array2 (void) : Array<T> ()
  343. {
  344.   d1 = 0;
  345.   d2 = 0;
  346. }
  347.  
  348. template <class T>
  349. Array2<T>::Array2 (int n, int m) : Array<T> (n*m)
  350. {
  351.   d1 = n;
  352.   d2 = m;
  353. }
  354.  
  355. template <class T>
  356. Array2<T>::Array2 (int n, int m, const T& val) : Array<T> (n*m, val)
  357. {
  358.   d1 = n;
  359.   d2 = m;
  360. }
  361.  
  362. template <class T>
  363. Array2<T>::Array2 (const Array2<T>& a) : Array<T> (a)
  364. {
  365.   d1 = a.d1;
  366.   d2 = a.d2;
  367. }
  368.  
  369. template <class T>
  370. Array2<T>::Array2 (const DiagArray<T>& a)
  371.   : Array<T> (a.rows () * a.cols (), T (0))
  372. {
  373.   for (int i = 0; i < a.length (); i++)
  374.     elem (i, i) = a.elem (i, i);
  375. }
  376.  
  377. template <class T>
  378. Array2<T>&
  379. Array2<T>::operator = (const Array2<T>& a)
  380. {
  381.   if (this != &a)
  382.     {
  383.       Array<T>::operator = (a);
  384.       d1 = a.d1;
  385.       d2 = a.d2;
  386.     }
  387.  
  388.   return *this;
  389. }
  390.  
  391. template <class T>
  392. int
  393. Array2<T>::dim1 (void) const
  394. {
  395.   return d1;
  396. }
  397.  
  398. template <class T>
  399. int
  400. Array2<T>::dim2 (void) const
  401. {
  402.   return d2;
  403. }
  404.  
  405. template <class T>
  406. int
  407. Array2<T>::rows (void) const
  408. {
  409.   return d1;
  410. }
  411.  
  412. template <class T>
  413. int
  414. Array2<T>::cols (void) const
  415. {
  416.   return d2;
  417. }
  418.  
  419. template <class T>
  420. int
  421. Array2<T>::columns (void) const
  422. {
  423.   return d2;
  424. }
  425.  
  426. template <class T>
  427. T&
  428. Array2<T>::elem (int i, int j)
  429. {
  430.   return Array<T>::elem (d1*j+i);
  431. }
  432.  
  433. template <class T>
  434. T&
  435. Array2<T>::checkelem (int i, int j)
  436. {
  437.   if (i < 0 || j < 0 || i >= d1 || j >= d2)
  438.     {
  439.       (*current_liboctave_error_handler) ("range error");
  440.       static T foo;
  441.       return foo;
  442.     }
  443.   return Array<T>::elem (d1*j+i);
  444. }
  445.  
  446. template <class T>
  447. T&
  448. Array2<T>::operator () (int i, int j)
  449. {
  450.   if (i < 0 || j < 0 || i >= d1 || j >= d2)
  451.     {
  452.       (*current_liboctave_error_handler) ("range error");
  453.       static T foo;
  454.       return foo;
  455.     }
  456.   return Array<T>::elem (d1*j+i);
  457. }
  458.  
  459. template <class T>
  460. T&
  461. Array2<T>::xelem (int i, int j)
  462. {
  463.   return Array<T>::xelem (d1*j+i);
  464. }
  465.  
  466. template <class T>
  467. T
  468. Array2<T>::elem (int i, int j) const
  469. {
  470.   return Array<T>::elem (d1*j+i);
  471. }
  472.  
  473. template <class T>
  474. T
  475. Array2<T>::checkelem (int i, int j) const
  476. {
  477.   if (i < 0 || j < 0 || i >= d1 || j >= d2)
  478.     {
  479.       (*current_liboctave_error_handler) ("range error");
  480.       T foo;
  481.       return foo;
  482.     }
  483.   return Array<T>::elem (d1*j+i);
  484. }
  485.  
  486. template <class T>
  487. T
  488. Array2<T>::operator () (int i, int j) const
  489. {
  490.   if (i < 0 || j < 0 || i >= d1 || j >= d2)
  491.     {
  492.       (*current_liboctave_error_handler) ("range error");
  493.       T foo;
  494.       return foo;
  495.     }
  496.   return Array<T>::elem (d1*j+i);
  497. }
  498.  
  499. template <class T>
  500. void
  501. Array2<T>::resize (int r, int c)
  502. {
  503.   if (r < 0 || c < 0)
  504.     {
  505.       (*current_liboctave_error_handler)
  506.     ("can't resize to negative dimension");
  507.       return;
  508.     }
  509.  
  510.   if (r == dim1 () && c == dim2 ())
  511.     return;
  512.  
  513.   ArrayRep<T> *old_rep = rep;
  514.   const T *old_data = data ();
  515.   int old_d1 = dim1 ();
  516.   int old_d2 = dim2 ();
  517.   int old_len = length ();
  518.  
  519.   rep = new ArrayRep<T> (r*c);
  520.   rep->count = 1;
  521.  
  522.   d1 = r;
  523.   d2 = c;
  524.  
  525.   if (old_data && old_len > 0)
  526.     {
  527.       int min_r = old_d1 < r ? old_d1 : r;
  528.       int min_c = old_d2 < c ? old_d2 : c;
  529.  
  530.       for (int j = 0; j < min_c; j++)
  531.     for (int i = 0; i < min_r; i++)
  532.       xelem (i, j) = old_data[old_d1*j+i];
  533.     }
  534.  
  535.   if (--old_rep->count <= 0)
  536.     delete old_rep;
  537. }
  538.  
  539. template <class T>
  540. void
  541. Array2<T>::resize (int r, int c, const T& val)
  542. {
  543.   if (r < 0 || c < 0)
  544.     {
  545.       (*current_liboctave_error_handler)
  546.     ("can't resize to negative dimension");
  547.       return;
  548.     }
  549.  
  550.   if (r == dim1 () && c == dim2 ())
  551.     return;
  552.  
  553.   ArrayRep<T> *old_rep = rep;
  554.   const T *old_data = data ();
  555.   int old_d1 = dim1 ();
  556.   int old_d2 = dim2 ();
  557.   int old_len = length ();
  558.  
  559.   rep = new ArrayRep<T> (r*c);
  560.   rep->count = 1;
  561.  
  562.   d1 = r;
  563.   d2 = c;
  564.  
  565.   int min_r = old_d1 < r ? old_d1 : r;
  566.   int min_c = old_d2 < c ? old_d2 : c;
  567.  
  568.   int i, j;
  569.  
  570.   if (old_data && old_len > 0)
  571.     {
  572.       for (j = 0; j < min_c; j++)
  573.     for (i = 0; i < min_r; i++)
  574.       xelem (i, j) = old_data[old_d1*j+i];
  575.     }
  576.  
  577.   for (j = 0; j < min_c; j++)
  578.     for (i = min_r; i < r; i++)
  579.       xelem (i, j) = val;
  580.  
  581.   for (j = min_c; j < c; j++)
  582.     for (i = 0; i < r; i++)
  583.       xelem (i, j) = val;
  584.  
  585.   if (--old_rep->count <= 0)
  586.     delete old_rep;
  587. }
  588.  
  589. /*
  590.  * Three dimensional array class.
  591.  */
  592.  
  593. template <class T>
  594. Array3<T>::Array3 (T *d, int n, int m, int k) : Array2<T> (d, n, m*k)
  595. {
  596.   d2 = m;
  597.   d3 = k;
  598. }
  599.  
  600. template <class T>
  601. Array3<T>::Array3 (void) : Array2<T> ()
  602. {
  603.   d2 = 0;
  604.   d3 = 0;
  605. }
  606.  
  607. template <class T>
  608. Array3<T>::Array3 (int n, int m, int k) : Array2<T> (n, m*k)
  609. {
  610.   d2 = m;
  611.   d3 = k;
  612. }
  613.  
  614. template <class T>
  615. Array3<T>::Array3 (int n, int m, int k, const T& val) : Array2<T> (n, m*k, val)
  616. {
  617.   d2 = m;
  618.   d3 = k;
  619. }
  620.  
  621. template <class T>
  622. Array3<T>::Array3 (const Array3<T>& a) : Array2<T> (a)
  623. {
  624.   d2 = a.d2;
  625.   d3 = a.d3;
  626. }
  627.  
  628. template <class T>
  629. Array3<T>&
  630. Array3<T>::operator = (const Array3<T>& a)
  631. {
  632.   if (this != &a)
  633.     {
  634.       Array<T>::operator = (a);
  635.       d1 = a.d1;
  636.       d2 = a.d2;
  637.       d3 = a.d3;
  638.     }
  639.  
  640.   return *this;
  641. }
  642.  
  643. template <class T>
  644. int
  645. Array3<T>::dim3 (void) const
  646. {
  647.   return d3;
  648. }
  649.  
  650. template <class T>
  651. T&
  652. Array3<T>::elem (int i, int j, int k)
  653. {
  654.   return Array2<T>::elem (i, d2*k+j);
  655. }
  656.  
  657. template <class T>
  658. T&
  659. Array3<T>::checkelem (int i, int j, int k)
  660. {
  661.   if (i < 0 || j < 0 || k < 0 || i >= d1 || j >= d2 || k >= d3)
  662.     {
  663.       (*current_liboctave_error_handler) ("range error");
  664.       static T foo;
  665.       return foo;
  666.     }
  667.   return Array2<T>::elem (i, d1*k+j);
  668. }
  669.  
  670. template <class T>
  671. T&
  672. Array3<T>::operator () (int i, int j, int k)
  673. {
  674.   if (i < 0 || j < 0 || k < 0 || i >= d1 || j >= d2 || k >= d3)
  675.     {
  676.       (*current_liboctave_error_handler) ("range error");
  677.       static T foo;
  678.       return foo;
  679.     }
  680.   return Array2<T>::elem (i, d2*k+j);
  681. }
  682.  
  683. template <class T>
  684. T&
  685. Array3<T>::xelem (int i, int j, int k)
  686. {
  687.   return Array2<T>::xelem (i, d2*k+j);
  688. }
  689.  
  690. template <class T>
  691. T
  692. Array3<T>::elem (int i, int j, int k) const
  693. {
  694.   return Array2<T>::elem (i, d2*k+j);
  695. }
  696.  
  697. template <class T>
  698. T
  699. Array3<T>::checkelem (int i, int j, int k) const
  700. {
  701.   if (i < 0 || j < 0 || k < 0 || i >= d1 || j >= d2 || k >= d3)
  702.     {
  703.       (*current_liboctave_error_handler) ("range error");
  704.       T foo;
  705.       return foo;
  706.     }
  707.   return Array2<T>::elem (i, d1*k+j);
  708. }
  709.  
  710. template <class T>
  711. T
  712. Array3<T>::operator () (int i, int j, int k) const
  713. {
  714.   if (i < 0 || j < 0 || k < 0 || i >= d1 || j >= d2 || k >= d3)
  715.     {
  716.       (*current_liboctave_error_handler) ("range error");
  717.       T foo;
  718.       return foo;
  719.     }
  720.   return Array2<T>::elem (i, d2*k+j);
  721. }
  722.  
  723. template <class T>
  724. void
  725. Array3<T>::resize (int n, int m, int k)
  726. {
  727.   assert (0); /* XXX FIXME XXX */
  728. }
  729.  
  730. template <class T>
  731. void
  732. Array3<T>::resize (int n, int m, int k, const T& val)
  733. {
  734.   assert (0); /* XXX FIXME XXX */
  735. }
  736.  
  737. /*
  738.  * A two-dimensional array with diagonal elements only.
  739.  */
  740.  
  741. template <class T>
  742. DiagArray<T>::DiagArray (T *d, int r, int c) : Array<T> (d, r < c ? r : c)
  743. {
  744.   nr = r;
  745.   nc = c;
  746. }
  747.  
  748. template <class T>
  749. DiagArray<T>::DiagArray (void) : Array<T> ()
  750. {
  751.   nr = 0;
  752.   nc = 0;
  753. }
  754.  
  755. template <class T>
  756. DiagArray<T>::DiagArray (int n) : Array<T> (n)
  757. {
  758.   nr = n;
  759.   nc = n;
  760. }
  761.  
  762. template <class T>
  763. DiagArray<T>::DiagArray (int n, const T& val) : Array<T> (n, val)
  764. {
  765.   nr = nc = n;
  766. }
  767.  
  768. template <class T>
  769. DiagArray<T>::DiagArray (int r, int c) : Array<T> (r < c ? r : c)
  770. {
  771.   nr = r;
  772.   nc = c;
  773. }
  774.  
  775. template <class T>
  776. DiagArray<T>::DiagArray (int r, int c, const T& val)
  777.   : Array<T> (r < c ? r : c, val)
  778. {
  779.   nr = r;
  780.   nc = c;
  781. }
  782.  
  783. template <class T>
  784. DiagArray<T>::DiagArray (const Array<T>& a) : Array<T> (a)
  785. {
  786.   nr = nc = a.length ();
  787. }
  788.  
  789. template <class T>
  790. DiagArray<T>::DiagArray (const DiagArray<T>& a) : Array<T> (a)
  791. {
  792.   nr = a.nr;
  793.   nc = a.nc;
  794. }
  795.  
  796. template <class T>
  797. DiagArray<T>&
  798. DiagArray<T>::operator = (const DiagArray<T>& a)
  799. {
  800.   if (this != &a)
  801.     {
  802.       Array<T>::operator = (a);
  803.       nr = a.nr;
  804.       nc = a.nc;
  805.     }
  806.  
  807.   return *this;
  808. }
  809.  
  810. template <class T>
  811. int
  812. DiagArray<T>::dim1 (void) const
  813. {
  814.   return nr;
  815. }
  816.  
  817. template <class T>
  818. int
  819. DiagArray<T>::dim2 (void) const
  820. {
  821.   return nc;
  822. }
  823.  
  824. template <class T>
  825. int
  826. DiagArray<T>::rows (void) const
  827. {
  828.   return nr;
  829. }
  830.  
  831. template <class T>
  832. int
  833. DiagArray<T>::cols (void) const
  834. {
  835.   return nc;
  836. }
  837.  
  838. template <class T>
  839. int
  840. DiagArray<T>::columns (void) const
  841. {
  842.   return nc;
  843. }
  844.  
  845. #if 1
  846. template <class T>
  847. T&
  848. DiagArray<T>::elem (int r, int c)
  849. {
  850.   static T foo (0);
  851.   return (r == c) ? Array<T>::elem (r) : foo;
  852. }
  853.  
  854. template <class T>
  855. T&
  856. DiagArray<T>::checkelem (int r, int c)
  857. {
  858.   static T foo (0);
  859.   if (r < 0 || c < 0 || r >= nr || c >= nc)
  860.     {
  861.       (*current_liboctave_error_handler) ("range error");
  862.       return foo;
  863.     }
  864.   return (r == c) ? Array<T>::elem (r) : foo;
  865. }
  866.  
  867. template <class T>
  868. T&
  869. DiagArray<T>::operator () (int r, int c)
  870. {
  871.   static T foo (0);
  872.   if (r < 0 || c < 0 || r >= nr || c >= nc)
  873.     {
  874.       (*current_liboctave_error_handler) ("range error");
  875.       return foo;
  876.     }
  877.   return (r == c) ? Array<T>::elem (r) : foo;
  878. }
  879. #endif
  880.  
  881. template <class T>
  882. T&
  883. DiagArray<T>::xelem (int r, int c)
  884. {
  885.   static T foo (0);
  886.   return (r == c) ? Array<T>::xelem (r) : foo;
  887. }
  888.  
  889. template <class T>
  890. T
  891. DiagArray<T>::elem (int r, int c) const
  892. {
  893.   return (r == c) ? Array<T>::elem (r) : T (0);
  894. }
  895.  
  896. template <class T>
  897. T
  898. DiagArray<T>::checkelem (int r, int c) const
  899. {
  900.   if (r < 0 || c < 0 || r >= nr || c >= nc)
  901.     {
  902.       (*current_liboctave_error_handler) ("range error");
  903.       T foo;
  904.       return foo;
  905.     }
  906.   return (r == c) ? Array<T>::elem (r) : T (0);
  907. }
  908.  
  909. template <class T>
  910. T
  911. DiagArray<T>::operator () (int r, int c) const
  912. {
  913.   if (r < 0 || c < 0 || r >= nr || c >= nc)
  914.     {
  915.       (*current_liboctave_error_handler) ("range error");
  916.       T foo;
  917.       return foo;
  918.     }
  919.   return (r == c) ? Array<T>::elem (r) : T (0);
  920. }
  921.  
  922. template <class T>
  923. void
  924. DiagArray<T>::resize (int r, int c)
  925. {
  926.   if (r < 0 || c < 0)
  927.     {
  928.       (*current_liboctave_error_handler)
  929.     ("can't resize to negative dimensions");
  930.       return;
  931.     }
  932.  
  933.   if (r == dim1 () && c == dim2 ())
  934.     return;
  935.  
  936.   ArrayRep<T> *old_rep = rep;
  937.   const T *old_data = data ();
  938.   int old_len = length ();
  939.  
  940.   int new_len = r < c ? r : c;
  941.  
  942.   rep = new ArrayRep<T> (new_len);
  943.   rep->count = 1;
  944.  
  945.   nr = r;
  946.   nc = c;
  947.  
  948.   if (old_data && old_len > 0)
  949.     {
  950.       int min_len = old_len < new_len ? old_len : new_len;
  951.  
  952.       for (int i = 0; i < min_len; i++)
  953.     xelem (i, i) = old_data[i];
  954.     }
  955.  
  956.   if (--old_rep->count <= 0)
  957.     delete old_rep;
  958. }
  959.  
  960. template <class T>
  961. void
  962. DiagArray<T>::resize (int r, int c, const T& val)
  963. {
  964.   if (r < 0 || c < 0)
  965.     {
  966.       (*current_liboctave_error_handler)
  967.     ("can't resize to negative dimensions");
  968.       return;
  969.     }
  970.  
  971.   if (r == dim1 () && c == dim2 ())
  972.     return;
  973.  
  974.   ArrayRep<T> *old_rep = rep;
  975.   const T *old_data = data ();
  976.   int old_len = length ();
  977.  
  978.   int new_len = r < c ? r : c;
  979.  
  980.   rep = new ArrayRep<T> (new_len);
  981.   rep->count = 1;
  982.  
  983.   nr = r;
  984.   nc = c;
  985.  
  986.   int min_len = old_len < new_len ? old_len : new_len;
  987.  
  988.   if (old_data && old_len > 0)
  989.     {
  990.       for (int i = 0; i < min_len; i++)
  991.     xelem (i, i) = old_data[i];
  992.     }
  993.  
  994.   for (int i = min_len; i < new_len; i++)
  995.     xelem (i, i) = val;
  996.  
  997.   if (--old_rep->count <= 0)
  998.     delete old_rep;
  999. }
  1000.  
  1001. /*
  1002. ;;; Local Variables: ***
  1003. ;;; mode: C++ ***
  1004. ;;; page-delimiter: "^/\\*" ***
  1005. ;;; End: ***
  1006. */
  1007.