00001 /* 00002 00003 Copyright (C) 1994-2012 John W. Eaton 00004 Copyright (C) 2009 VZLU Prague 00005 00006 This file is part of Octave. 00007 00008 Octave is free software; you can redistribute it and/or modify it 00009 under the terms of the GNU General Public License as published by the 00010 Free Software Foundation; either version 3 of the License, or (at your 00011 option) any later version. 00012 00013 Octave is distributed in the hope that it will be useful, but WITHOUT 00014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00015 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 00016 for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with Octave; see the file COPYING. If not, see 00020 <http://www.gnu.org/licenses/>. 00021 00022 */ 00023 00024 #ifdef HAVE_CONFIG_H 00025 #include <config.h> 00026 #endif 00027 00028 #include "error.h" 00029 #include "oct-obj.h" 00030 #include "Cell.h" 00031 00032 // We are likely to have a lot of octave_value_list objects to allocate, 00033 // so make the grow_size large. 00034 DEFINE_OCTAVE_ALLOCATOR2(octave_value_list, 1024); 00035 00036 octave_value_list::octave_value_list (const std::list<octave_value_list>& lst) 00037 { 00038 octave_idx_type n = 0, nel = 0; 00039 00040 // Determine number. 00041 for (std::list<octave_value_list>::const_iterator p = lst.begin (); 00042 p != lst.end (); p++) 00043 { 00044 n++; 00045 nel += p->length (); 00046 } 00047 00048 // Optimize single-element case 00049 if (n == 1) 00050 data = lst.front ().data; 00051 else if (nel > 0) 00052 { 00053 data.resize (dim_vector (1, nel)); 00054 octave_idx_type k = 0; 00055 for (std::list<octave_value_list>::const_iterator p = lst.begin (); 00056 p != lst.end (); p++) 00057 { 00058 data.assign (idx_vector (k, k + p->length ()), p->data); 00059 k += p->length (); 00060 } 00061 assert (k == nel); 00062 } 00063 00064 } 00065 00066 octave_value_list& 00067 octave_value_list::prepend (const octave_value& val) 00068 { 00069 octave_idx_type n = length (); 00070 00071 resize (n + 1); 00072 00073 while (n > 0) 00074 { 00075 elem (n) = elem (n - 1); 00076 n--; 00077 } 00078 00079 elem (0) = val; 00080 00081 return *this; 00082 } 00083 00084 octave_value_list& 00085 octave_value_list::append (const octave_value& val) 00086 { 00087 octave_idx_type n = length (); 00088 00089 resize (n + 1); 00090 00091 elem (n) = val; 00092 00093 return *this; 00094 } 00095 00096 octave_value_list& 00097 octave_value_list::append (const octave_value_list& lst) 00098 { 00099 octave_idx_type len = length (); 00100 octave_idx_type lst_len = lst.length (); 00101 00102 resize (len + lst_len); 00103 00104 for (octave_idx_type i = 0; i < lst_len; i++) 00105 elem (len + i) = lst (i); 00106 00107 return *this; 00108 } 00109 00110 octave_value_list& 00111 octave_value_list::reverse (void) 00112 { 00113 octave_idx_type n = length (); 00114 00115 for (octave_idx_type i = 0; i < n / 2; i++) 00116 { 00117 octave_value tmp = elem (i); 00118 elem (i) = elem (n - i - 1); 00119 elem (n - i - 1) = tmp; 00120 } 00121 00122 return *this; 00123 } 00124 00125 octave_value_list 00126 octave_value_list::splice (octave_idx_type offset, octave_idx_type rep_length, 00127 const octave_value_list& lst) const 00128 { 00129 octave_value_list retval; 00130 00131 octave_idx_type len = length (); 00132 00133 if (offset < 0 || offset >= len) 00134 { 00135 if (! (rep_length == 0 && offset == len)) 00136 { 00137 error ("octave_value_list::splice: invalid OFFSET"); 00138 return retval; 00139 } 00140 } 00141 00142 if (rep_length < 0 || rep_length + offset > len) 00143 { 00144 error ("octave_value_list::splice: invalid LENGTH"); 00145 return retval; 00146 } 00147 00148 octave_idx_type lst_len = lst.length (); 00149 00150 octave_idx_type new_len = len - rep_length + lst_len; 00151 00152 retval.resize (new_len); 00153 00154 octave_idx_type k = 0; 00155 00156 for (octave_idx_type i = 0; i < offset; i++) 00157 retval(k++) = elem (i); 00158 00159 for (octave_idx_type i = 0; i < lst_len; i++) 00160 retval(k++) = lst(i); 00161 00162 for (octave_idx_type i = offset + rep_length; i < len; i++) 00163 retval(k++) = elem (i); 00164 00165 return retval; 00166 } 00167 00168 bool 00169 octave_value_list::all_strings_p (void) const 00170 { 00171 octave_idx_type n = length (); 00172 00173 for (octave_idx_type i = 0; i < n; i++) 00174 if (! elem(i).is_string ()) 00175 return false; 00176 00177 return true; 00178 } 00179 00180 bool 00181 octave_value_list::all_scalars (void) const 00182 { 00183 octave_idx_type n = length (); 00184 00185 for (octave_idx_type i = 0; i < n; i++) 00186 { 00187 dim_vector dv = elem(i).dims (); 00188 if (! dv.all_ones ()) 00189 return false; 00190 } 00191 00192 return true; 00193 } 00194 00195 bool 00196 octave_value_list::any_cell (void) const 00197 { 00198 octave_idx_type n = length (); 00199 00200 for (octave_idx_type i = 0; i < n; i++) 00201 if (elem (i).is_cell ()) 00202 return true; 00203 00204 return false; 00205 } 00206 00207 bool 00208 octave_value_list::has_magic_colon (void) const 00209 { 00210 octave_idx_type n = length (); 00211 00212 for (octave_idx_type i = 0; i < n; i++) 00213 if (elem(i).is_magic_colon ()) 00214 return true; 00215 00216 return false; 00217 } 00218 00219 string_vector 00220 octave_value_list::make_argv (const std::string& fcn_name) const 00221 { 00222 string_vector argv; 00223 00224 if (all_strings_p ()) 00225 { 00226 octave_idx_type len = length (); 00227 00228 octave_idx_type total_nr = 0; 00229 00230 for (octave_idx_type i = 0; i < len; i++) 00231 { 00232 // An empty std::string ("") has zero columns and zero rows (a 00233 // change that was made for Matlab contemptibility. 00234 00235 octave_idx_type n = elem(i).rows (); 00236 00237 total_nr += n ? n : 1; 00238 } 00239 00240 octave_idx_type k = 0; 00241 if (! fcn_name.empty ()) 00242 { 00243 argv.resize (total_nr+1); 00244 argv[0] = fcn_name; 00245 k = 1; 00246 } 00247 else 00248 argv.resize (total_nr); 00249 00250 for (octave_idx_type i = 0; i < len; i++) 00251 { 00252 octave_idx_type nr = elem(i).rows (); 00253 00254 if (nr < 2) 00255 argv[k++] = elem(i).string_value (); 00256 else 00257 { 00258 string_vector tmp = elem(i).all_strings (); 00259 00260 for (octave_idx_type j = 0; j < nr; j++) 00261 argv[k++] = tmp[j]; 00262 } 00263 } 00264 } 00265 else 00266 error ("%s: expecting all arguments to be strings", fcn_name.c_str ()); 00267 00268 return argv; 00269 } 00270 00271 void 00272 octave_value_list::make_storable_values (void) 00273 { 00274 octave_idx_type len = length (); 00275 const Array<octave_value>& cdata = data; 00276 00277 for (octave_idx_type i = 0; i < len; i++) 00278 { 00279 // This is optimized so that we don't force a copy unless necessary. 00280 octave_value tmp = cdata(i).storable_value (); 00281 if (! tmp.is_copy_of (cdata (i))) 00282 data(i) = tmp; 00283 } 00284 }