00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 2008, 2009, Andrew W. Steiner 00005 00006 This file is part of O2scl. 00007 00008 O2scl is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 O2scl is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 00020 00021 ------------------------------------------------------------------- 00022 */ 00023 #ifndef O2SCL_COLLECTION_H 00024 #define O2SCL_COLLECTION_H 00025 00026 #include <iostream> 00027 #include <fstream> 00028 #include <string> 00029 #include <vector> 00030 #include <map> 00031 #include <set> 00032 #include <sstream> 00033 #include <o2scl/misc.h> 00034 #include <o2scl/err_hnd.h> 00035 #include <o2scl/test_mgr.h> 00036 #include <o2scl/text_file.h> 00037 #include <o2scl/file_format.h> 00038 #include <o2scl/file_detect.h> 00039 #include <o2scl/ovector_tlate.h> 00040 #include <o2scl/omatrix_tlate.h> 00041 #include <o2scl/ovector_cx_tlate.h> 00042 #include <o2scl/omatrix_cx_tlate.h> 00043 00044 /** \file collection.h 00045 \brief File containing I/O types and the collection class 00046 00047 New update todos: 00048 - There are a lot of blank functions in the io_base class, 00049 so this class should be made abstract. This can actually be done 00050 by separating io_base into two classes, so that the parents of 00051 the collection class and the io_tlate class are different. 00052 - Construct new templated add() function 00053 - Fix test_type() 00054 - Fix error handling in get() functions and make a lookup() method 00055 which doesn't necessarily call the error handler 00056 - Fix documentation? 00057 - Columnify summary output 00058 - Ensure all parameters are matched by parameter and name if possible 00059 00060 \future Figure out what to do with templated matrix and vector output. 00061 What might be ideal is a "vector_io" type which will input or output 00062 a generic vector of any type. 00063 */ 00064 00065 #ifndef DOXYGENP 00066 namespace o2scl { 00067 #endif 00068 00069 /** An entry in a collection 00070 00071 This class is experimental. 00072 */ 00073 typedef struct { 00074 /// The pointer to the object 00075 void *data; 00076 /// The first size parameter 00077 int size; 00078 /// The second size parameter 00079 int size2; 00080 /// True if the collection owns this object 00081 bool owner; 00082 /// A pointer to the corresponding \ref io_base object 00083 class io_base *iop; 00084 } collection_entry; 00085 00086 /** \brief A pointer output structure 00087 00088 This class is experimental. 00089 */ 00090 typedef struct { 00091 /// The name of the pointer 00092 std::string name; 00093 /// Pointer to the collection entry 00094 collection_entry *ep; 00095 /// True if the pointer has been written to the file 00096 bool output; 00097 } pointer_output; 00098 00099 /** \brief A pointer input structure 00100 00101 This class is experimental. 00102 */ 00103 typedef struct { 00104 /// The name of the pointer 00105 std::string name; 00106 /// The pointer 00107 void **ptr; 00108 /// The type of the object pointed to 00109 std::string stype; 00110 } pointer_input; 00111 00112 // Forward declaration of class cinput 00113 class cinput; 00114 // Forward declaration of class coutput 00115 class coutput; 00116 00117 /** 00118 \brief I/O base class 00119 00120 This class is experimental. 00121 00122 This class is necessary so that the collection method source code 00123 and the io_base method source code doesn't have to go in header files. 00124 00125 \todo Should the remove() functions be moved to class collection? 00126 */ 00127 class io_base { 00128 00129 #ifndef DOXYGEN_INTERNAL 00130 00131 protected: 00132 00133 /// for io_type_info.add_type(). 00134 friend class io_type_info; 00135 00136 /// for stat_in and stat_out 00137 friend class collection; 00138 00139 friend class cinput; 00140 friend class coutput; 00141 friend class io_manager; 00142 00143 /// A pointer to the type manager 00144 static class io_manager *iom; 00145 00146 /// A count of the number of objects 00147 static int objs_count; 00148 00149 /// Automatically create an object for stat_in 00150 virtual int stat_in_noobj(cinput *co, in_file_format *ins); 00151 00152 /// Automatically create an object for stat_out 00153 virtual int stat_out_noobj(coutput *co, out_file_format *outs); 00154 00155 /** \brief Allocate memory and input an object 00156 */ 00157 virtual int in_wrapper(cinput *co, in_file_format *ins, void *&vp); 00158 00159 /** \brief Allocate memory and input an array of objects 00160 */ 00161 virtual int in_wrapper(cinput *co, in_file_format *ins, void *&vp, 00162 int &sz); 00163 00164 /** \brief Allocate memory and input a 2-d array of objects 00165 */ 00166 virtual int in_wrapper(cinput *co, in_file_format *ins, void *&vp, 00167 int &sz, int &sz2); 00168 00169 /** \brief Internal function to output an object (or an array 00170 or 2-d array) 00171 */ 00172 virtual int out_wrapper(coutput *co, out_file_format *outs, 00173 void *vp, int sz, int sz2); 00174 00175 /// Input an object (no memory allocation) 00176 virtual int object_in_void(cinput *cin, in_file_format *ins, void *op, 00177 std::string &name); 00178 00179 /// Input an array of objects (no memory allocation) 00180 virtual int object_in_void(cinput *cin, in_file_format *ins, void *op, 00181 int sz, std::string &name); 00182 00183 /// Input a 2-d array of objects (no memory allocation) 00184 virtual int object_in_void(cinput *cin, in_file_format *ins, void *op, 00185 int sz, int sz2, std::string &name); 00186 00187 /// Input an object (no memory allocation) 00188 virtual int object_in_mem_void(cinput *cin, in_file_format *ins, 00189 void *&op, std::string &name); 00190 00191 /// Input an array of objects (no memory allocation) 00192 virtual int object_in_mem_void(cinput *cin, in_file_format *ins, 00193 void *&op, int &sz, std::string &name); 00194 00195 /// Input a 2-d array of objects (no memory allocation) 00196 virtual int object_in_mem_void(cinput *cin, in_file_format *ins, 00197 void *&op, int &sz, int &sz2, 00198 std::string &name); 00199 00200 /// Output an object, an array of objects, or a 2-d array of objects 00201 virtual int object_out_void(coutput *cout, out_file_format *outs, 00202 void *op, int sz, int sz2, 00203 std::string name=""); 00204 00205 /** \brief Store the value of \c sw given in the constructor so 00206 that we know if we need to remove the type in the destructor 00207 */ 00208 int sw_store; 00209 00210 /** \name Functions to remove the memory that was allocated for an object 00211 */ 00212 //@{ 00213 /// Remove the memory for an object 00214 virtual int remove(void *vp) { return 0; } 00215 00216 /// Remove the memory for an array of objects 00217 virtual int remove_arr(void *vp) { 00218 return 0; 00219 } 00220 00221 /// Remove the memory for a 2-dimensional array of objects 00222 virtual int remove_2darr(void *vp, int sz) { return 0; } 00223 //@} 00224 00225 #endif 00226 00227 public: 00228 00229 /** 00230 \brief Create a new I/O object 00231 00232 If \c sw is different from zero, then the type will not 00233 be added to the io_manager. This is useful if you want 00234 an object to be its own I/O class, in which case you 00235 may want to make sure that the io_manager only tries 00236 to add the type once. There is no need to have an I/O 00237 object for every instance of a particular type. 00238 */ 00239 io_base(int sw=0); 00240 00241 /** \brief Create a new object only if an I/O object for type \c t 00242 is not yet present 00243 */ 00244 io_base(const char *t); 00245 00246 virtual ~io_base(); 00247 00248 /// \name Functions to be overloaded in descendants of io_base 00249 //@{ 00250 /// Return the type of an object 00251 virtual const char *type() { return "io_base"; } 00252 00253 /// If true, then the object contains static data 00254 virtual bool has_static_data() { return false; } 00255 //@} 00256 00257 /** \name Functions useful for in in() and out() 00258 */ 00259 //@{ 00260 /// Input a pointer 00261 virtual int pointer_in(cinput *co, in_file_format *ins, void **pp, 00262 std::string &stype); 00263 00264 /** 00265 \brief Output an object to \c outs of type \c stype 00266 00267 This is useful for to output a pointer to an object in the 00268 out() or stat_out() functions for a class. The data for 00269 the object which is pointed to is separate from the object 00270 and is only referred to once if more than one objects 00271 point to it. 00272 */ 00273 virtual int pointer_out(coutput *co, out_file_format *outs, void *ptr, 00274 std::string stype); 00275 //@} 00276 00277 }; 00278 00279 /** 00280 \brief Manage I/O type information 00281 00282 This class is experimental. 00283 00284 This class is automatically created, utilized, and destroyed by 00285 \ref io_base. It's sole constructor is protected, so it cannot 00286 be created by a generic end-user. 00287 */ 00288 class io_manager { 00289 00290 public: 00291 00292 /** 00293 \brief Add a type to the list 00294 00295 Unfortunately, add_type() cannot ensure that no type is added 00296 more than once, since the type is not specified until the 00297 entire constructor hierarchy has been executed and add_type() 00298 is called at the top of this hierarchy. 00299 */ 00300 int add_type(io_base *iop); 00301 00302 /// Return 0 if \c iop points to a valid type 00303 int is_type(io_base *iop); 00304 00305 /// Add type \c iop to the manager assuming the type name \c t 00306 int add_type(io_base *iop, const char *t); 00307 00308 /// Remove a type from the list 00309 int remove_type(io_base *iop); 00310 00311 #ifndef DOXYGEN_INTERNAL 00312 00313 protected: 00314 00315 /// So that io_base can access add_type(). 00316 friend class io_base; 00317 00318 /// So that collections can access get_ptr 00319 friend class collection; 00320 00321 /// So that cinputs can access get_ptr() 00322 friend class cinput; 00323 00324 /// So that coutputs can access get_ptr() 00325 friend class coutput; 00326 00327 // So that io_type_info can access tlist 00328 friend class io_type_info; 00329 00330 /// Get a pointer to type \c stype 00331 io_base *get_ptr(std::string stype); 00332 00333 /// The list of types in the form of io_base pointers 00334 std::vector<io_base *> tlist; 00335 00336 /// A useful definition for iterating through types 00337 typedef std::vector<io_base *>::iterator titer; 00338 00339 /// Empty constructor 00340 io_manager() {}; 00341 00342 #endif 00343 00344 }; 00345 00346 // ---------------------------------------------------------------- 00347 // Start of class io_type_info 00348 // ---------------------------------------------------------------- 00349 00350 /** 00351 \brief User interface to provide I/O type information 00352 00353 This class is experimental. 00354 */ 00355 class io_type_info : public io_base { 00356 00357 #ifndef DOXYGEN_INTERNAL 00358 00359 protected: 00360 00361 /// So that collection::fout() can access static_fout(). 00362 friend class collection; 00363 00364 /// Output the static information for the I/O types 00365 int static_fout(coutput *co, out_file_format *out); 00366 00367 /// Output the static information for the I/O types not in the list 00368 int static_fout_restricted(coutput *co, out_file_format *out, 00369 std::set<std::string,string_comp> list); 00370 00371 /// A useful definition for iterating through types 00372 typedef std::vector<io_base *>::iterator titer; 00373 00374 #endif 00375 00376 public: 00377 00378 io_type_info(); 00379 00380 virtual ~io_type_info(); 00381 00382 /** \name Type manipulation 00383 */ 00384 //@{ 00385 00386 /// Return 0 if \c stype is a valid I/O type 00387 int is_type(std::string stype); 00388 00389 /** 00390 \brief Remove \c stype from the list of valid I/O types 00391 00392 This method is dangerous, as it can't check to ensure that 00393 no collection has remaining objects of the type to be 00394 removed. 00395 */ 00396 int remove_type(std::string stype); 00397 00398 /** 00399 \brief Remove all types in the list of valid I/O types 00400 00401 This method is dangerous as it doesn't ensure that 00402 all collections are empty. 00403 */ 00404 virtual int clear_types(); 00405 00406 /// Print a summary of valid types to the \c outs stream 00407 void type_summary(std::ostream *outs, bool pointers=false); 00408 00409 /// Add an I/O type to the list 00410 int add_type(io_base *iop) { return iom->add_type(iop); } 00411 //@} 00412 00413 }; 00414 00415 // ---------------------------------------------------------------- 00416 // End of class io_type_info 00417 // ---------------------------------------------------------------- 00418 00419 // ---------------------------------------------------------------- 00420 // Start of class collection 00421 // ---------------------------------------------------------------- 00422 00423 /** 00424 \brief Collection of objects 00425 00426 This class is experimental. 00427 00428 By default, the fout() functions alphabetize the objects by name, 00429 but this is not a requirement for files read using fin(). 00430 00431 Important issues: 00432 1. Pointers are not set until after an entire file is read so that 00433 objects that are pointed to may occur anywhere in a file. This 00434 means that the information that is pointed to cannot be used in 00435 the io_tlate_d::input() function. 00436 00437 \todo 00438 - If pointer_in gets a null pointer it does nothing. Should we 00439 replace this behaviour by two pointer_in() functions. One which 00440 does nothing if it gets a null pointer, and one which will 00441 go ahead and set the pointer to null. This is useful for 00442 output object which have default values to be used if 00443 they are given a null pointer. 00444 - More testing on rewrite() function. 00445 - Think more about adding arrays of pointers? pointers to arrays? 00446 - Modify static data output so that if no objects of a type 00447 are included, then no static data is output for that type? 00448 (No, it's too hard to go through all objects looking for 00449 an object of a particular type). 00450 00451 \bug 00452 - Ensure that the user cannot add a object with a name of ptrXXX. 00453 - Test_type does not test handle static data or pointers. 00454 - Check strings and words for characters that we can't handle 00455 - The present version of a text-file requires 00456 strings to contain at least one printable character. 00457 - Ensure that all matching is done by both type and name if 00458 possible. 00459 00460 Structure: 00461 collection::fout() does the following: 00462 - create an object of type coutput 00463 - Add all objects in the list to the pointer map \c ptr_map 00464 (with \c output=true ) so that they can be referred to by 00465 pointers later 00466 - Output all static data using io_type_info::static_fout() 00467 - Output all of the items in the list \c plist (see 00468 below). Any pointers which are not already in \c ptr_map are 00469 added at this point (with \c output=false 00470 - Call coutput::pointer_map_fout() to output all objects that 00471 were referred to but not in the list 00472 00473 To output individual items, collection::fout() does the following: 00474 - Call either io_base::out_wrapper() or io_base::out_hc_wrapper() 00475 - In turn, these functions call io_base::output(), which the user 00476 has overloaded 00477 - If the function io_base::output() calls io_tlate::object_out() then the 00478 io_base::output() function appropriate for that object is called. 00479 No type or name information is included, but size integers are 00480 included if the object is a 1- or 2-d array. 00481 - If the function io_base::output() calls io_base::pointer_out(), then 00482 the object is searched for in the \c ptr_map . If it is 00483 not there, then the object is added and assigned a name. The 00484 type and name are then output. If the pointer is 0, then 00485 both the type and the name are set to \c null . 00486 00487 */ 00488 class collection : public io_base { 00489 00490 #ifndef DOXYGEN_INTERNAL 00491 00492 protected: 00493 00494 friend class io_base; 00495 friend class cinput; 00496 friend class coutput; 00497 00498 /// A convenient iterator definition for the collection 00499 typedef std::map<std::string,collection_entry,string_comp>::iterator 00500 piter; 00501 00502 /// The actual collection 00503 std::map<std::string,collection_entry,string_comp> plist; 00504 00505 #endif 00506 00507 public: 00508 00509 collection() : io_base(1) {}; 00510 00511 #ifdef O2SCL_NEVER_DEFINED 00512 // This is just to assist emacs tabification 00513 } 00514 { 00515 #endif 00516 00517 ~collection(); 00518 00519 /** \name Output to file methods */ 00520 //@{ 00521 00522 /// Output entire list to \c outs 00523 int fout(out_file_format *outs); 00524 00525 /// Output entire list to a text file named \c filename 00526 int fout(std::string filename); 00527 //@} 00528 00529 /** \name Input from file methods 00530 If \c overwrt is true, then any objects which 00531 already exist with the same name are overwritten 00532 with the objects in the file. The collection 00533 owns all the objects read. (Since it created them, 00534 the collection assumes it ought to be responsible 00535 to destroy them.) 00536 */ 00537 //@{ 00538 /// Read a collection from text file named \c file_name 00539 int fin(std::string file_name, bool overwrt=false, int verbose=0); 00540 00541 /// Read a collection from \c ins 00542 int fin(in_file_format *ins, bool overwrt=false, int verbose=0); 00543 //@} 00544 00545 /** \name Miscellaneous methods 00546 */ 00547 //@{ 00548 00549 /// Test the output for type \c stype. 00550 int test_type(o2scl::test_mgr &t, std::string stype, void *obj, 00551 void *&newobj, bool scrout=false); 00552 00553 /** 00554 \brief Update a file containing a collection 00555 00556 This method loads the file from "fin" and produces a file at 00557 "fout" containing all of the objects from "fin", updated by 00558 their new values in the present list if possible. Then, it adds 00559 to the end of "fout" any objects in the present list that were 00560 not originally contained in "fin". 00561 */ 00562 int rewrite(std::string in_name, std::string out_name); 00563 00564 /** \brief Force the collection to assume that the ownership 00565 of \c name is external. 00566 00567 This allows the user to take over ownership of the object 00568 named \c name. This is particularly useful if the object is 00569 read from a file (since then object is owned initially by the 00570 collection), and you want to delete the collection, but retain 00571 the object. 00572 */ 00573 int disown(std::string name); 00574 00575 /** \brief Summarize contents of collection 00576 */ 00577 int summary(std::ostream *out, bool show_addresses=false); 00578 00579 /** 00580 \brief Remove an object for the collection 00581 00582 Free the memory \c name if it is owned by the collection 00583 and then remove it from the collection. 00584 */ 00585 int remove(std::string name); 00586 00587 /** \brief Remove all objects from the list 00588 */ 00589 void clear(); 00590 00591 /** 00592 \brief Count number of objects */ 00593 int size(); 00594 00595 //@} 00596 00597 /** \name Generic add methods 00598 00599 If \c overwrt is true, then any objects which already exist 00600 with the same name as \c name are overwritten. If owner=true, 00601 then the collection will own the memory allocated for the 00602 object and will free that memory with delete when the object 00603 is removed or the collection is deleted. 00604 */ 00605 //@{ 00606 int add_void(std::string name, io_base *tio, void *vec, int sz=0, 00607 int sz2=0, bool overwrt=true, bool owner=false); 00608 00609 int add_void(std::string name, std::string stype, 00610 void *vec, int sz=0, int sz2=0, 00611 bool overwrt=true, bool owner=false); 00612 //@} 00613 00614 /// \name Machine type get methods 00615 //@{ 00616 /// Get a boolean value named \c name with default value \c def_value 00617 bool getb_def(std::string name, bool def_value) { 00618 piter pit=plist.find(name); 00619 if (pit!=plist.end()) { 00620 if (((std::string)pit->second.iop->type())=="bool") { 00621 if (pit->second.size!=0 || pit->second.size2!=0) { 00622 O2SCL_ERR("Size of object incorrect in collection::getc2().", 00623 gsl_efailed); 00624 return 0; 00625 } 00626 bool *wp=(bool *)(pit->second.data); 00627 return *wp; 00628 } 00629 } 00630 return def_value; 00631 } 00632 00633 /// Get a char named \c name with default value \c def_value 00634 char getc_def(std::string name, char def_value) { 00635 piter pit=plist.find(name); 00636 if (pit!=plist.end()) { 00637 if (((std::string)pit->second.iop->type())=="char") { 00638 if (pit->second.size!=0 || pit->second.size2!=0) { 00639 O2SCL_ERR("Size of object incorrect in collection::getc2().", 00640 gsl_efailed); 00641 return 0; 00642 } 00643 char *wp=(char *)(pit->second.data); 00644 return *wp; 00645 } 00646 } 00647 return def_value; 00648 } 00649 00650 /// Get a double named \c name with default value \c def_value 00651 double getd_def(std::string name, double def_value) { 00652 piter pit=plist.find(name); 00653 if (pit!=plist.end()) { 00654 if (((std::string)pit->second.iop->type())=="double") { 00655 if (pit->second.size!=0 || pit->second.size2!=0) { 00656 O2SCL_ERR("Size of object incorrect in collection::getd2().", 00657 gsl_efailed); 00658 return 0.0; 00659 } 00660 double *wp=(double *)(pit->second.data); 00661 return *wp; 00662 } 00663 } 00664 return def_value; 00665 } 00666 00667 /// Get an integer named \c name with default value \c def_value 00668 int geti_def(std::string name, int def_value) { 00669 piter pit=plist.find(name); 00670 if (pit!=plist.end()) { 00671 if (((std::string)pit->second.iop->type())=="int") { 00672 if (pit->second.size!=0 || pit->second.size2!=0) { 00673 O2SCL_ERR("Size of object incorrect in collection::geti2().", 00674 gsl_efailed); 00675 return 0; 00676 } 00677 int *wp=(int *)(pit->second.data); 00678 return *wp; 00679 } 00680 } 00681 return def_value; 00682 } 00683 00684 /// Get a string named \c name with default value \c def_value 00685 std::string gets_def(std::string name, std::string def_value) { 00686 piter pit=plist.find(name); 00687 if (pit!=plist.end()) { 00688 if (((std::string)pit->second.iop->type())=="string") { 00689 if (pit->second.size!=0 || pit->second.size2!=0) { 00690 O2SCL_ERR("Size of object incorrect in collection::gets2().", 00691 gsl_efailed); 00692 return ""; 00693 } 00694 std::string *wp=(std::string *)(pit->second.data); 00695 return *wp; 00696 } 00697 } 00698 return def_value; 00699 } 00700 00701 /// Get a boolean value named \c name with default value \c def_value 00702 std::string getw_def(std::string name, std::string def_value) { 00703 piter pit=plist.find(name); 00704 if (pit!=plist.end()) { 00705 if (((std::string)pit->second.iop->type())=="word") { 00706 if (pit->second.size!=0 || pit->second.size2!=0) { 00707 O2SCL_ERR("Size of object incorrect in collection::getw2().", 00708 gsl_efailed); 00709 return ""; 00710 } 00711 std::string *wp=(std::string *)(pit->second.data); 00712 return *wp; 00713 } 00714 } 00715 return def_value; 00716 } 00717 00718 /// Desc 00719 bool getb(std::string name) { 00720 piter pit=plist.find(name); 00721 if (pit!=plist.end()) { 00722 if (((std::string)pit->second.iop->type())=="bool") { 00723 if (pit->second.size!=0 || pit->second.size2!=0) { 00724 O2SCL_ERR("Size of object incorrect in collection::getc2().", 00725 gsl_efailed); 00726 return 0; 00727 } 00728 bool *wp=(bool *)(pit->second.data); 00729 return *wp; 00730 } 00731 } 00732 O2SCL_ERR("Object not found in collection::getc2().",gsl_enotfound); 00733 return false; 00734 } 00735 00736 /// Desc 00737 char getc(std::string name) { 00738 piter pit=plist.find(name); 00739 if (pit!=plist.end()) { 00740 if (((std::string)pit->second.iop->type())=="char") { 00741 if (pit->second.size!=0 || pit->second.size2!=0) { 00742 O2SCL_ERR("Size of object incorrect in collection::getc2().", 00743 gsl_efailed); 00744 return 0; 00745 } 00746 char *wp=(char *)(pit->second.data); 00747 return *wp; 00748 } 00749 } 00750 O2SCL_ERR("Object not found in collection::getc2().",gsl_enotfound); 00751 return 0; 00752 } 00753 00754 /// Desc 00755 double getd(std::string name) { 00756 piter pit=plist.find(name); 00757 if (pit!=plist.end()) { 00758 if (((std::string)pit->second.iop->type())=="double") { 00759 if (pit->second.size!=0 || pit->second.size2!=0) { 00760 O2SCL_ERR("Size of object incorrect in collection::getd2().", 00761 gsl_efailed); 00762 return 0.0; 00763 } 00764 double *wp=(double *)(pit->second.data); 00765 return *wp; 00766 } 00767 } 00768 O2SCL_ERR("Object not found in collection::getd2().",gsl_enotfound); 00769 return 0.0; 00770 } 00771 00772 /// Desc 00773 int geti(std::string name) { 00774 piter pit=plist.find(name); 00775 if (pit!=plist.end()) { 00776 if (((std::string)pit->second.iop->type())=="int") { 00777 if (pit->second.size!=0 || pit->second.size2!=0) { 00778 O2SCL_ERR("Size of object incorrect in collection::geti2().", 00779 gsl_efailed); 00780 return 0; 00781 } 00782 int *wp=(int *)(pit->second.data); 00783 return *wp; 00784 } 00785 } 00786 O2SCL_ERR("Object not found in collection::geti2().",gsl_enotfound); 00787 return 0; 00788 } 00789 00790 /// Desc 00791 std::string gets(std::string name) { 00792 piter pit=plist.find(name); 00793 if (pit!=plist.end()) { 00794 if (((std::string)pit->second.iop->type())=="string") { 00795 if (pit->second.size!=0 || pit->second.size2!=0) { 00796 O2SCL_ERR("Size of object incorrect in collection::gets2().", 00797 gsl_efailed); 00798 return ""; 00799 } 00800 std::string *wp=(std::string *)(pit->second.data); 00801 return *wp; 00802 } 00803 } 00804 O2SCL_ERR("Object not found in collection::gets2().",gsl_enotfound); 00805 return ""; 00806 } 00807 00808 /// Desc 00809 std::string getw(std::string name) { 00810 piter pit=plist.find(name); 00811 if (pit!=plist.end()) { 00812 if (((std::string)pit->second.iop->type())=="word") { 00813 if (pit->second.size!=0 || pit->second.size2!=0) { 00814 O2SCL_ERR("Size of object incorrect in collection::getw2().", 00815 gsl_efailed); 00816 return ""; 00817 } 00818 std::string *wp=(std::string *)(pit->second.data); 00819 return *wp; 00820 } 00821 } 00822 O2SCL_ERR("Object not found in collection::getw2().",gsl_enotfound); 00823 return ""; 00824 } 00825 00826 00827 /// Desc 00828 int getb(std::string name, bool *&op, size_t &sz) { 00829 op=0; 00830 piter pit=plist.find(name); 00831 if (pit!=plist.end()) { 00832 if (((std::string)pit->second.iop->type())=="bool") { 00833 if (pit->second.size==0 || pit->second.size2!=0) { 00834 O2SCL_ERR_RET("Size of object incorrect in collection::get2().", 00835 gsl_efailed); 00836 } 00837 op=(bool *)(pit->second.data); 00838 sz=pit->second.size; 00839 return gsl_success; 00840 } 00841 } 00842 // 1/9/05 We choose not to set an error here in case 00843 // the user is legitimately looking for something 00844 // that they don't expect to find. 00845 // O2SCL_ERR(tname+" not found in get().",not_found); 00846 return gsl_enotfound; 00847 } 00848 00849 /// Desc 00850 int getb(std::string name, bool **&op, size_t &sz, 00851 size_t &sz2) { 00852 op=0; 00853 piter pit=plist.find(name); 00854 if (pit!=plist.end()) { 00855 if (((std::string)pit->second.iop->type())=="bool") { 00856 if (pit->second.size==0 || pit->second.size2==0) { 00857 O2SCL_ERR_RET("Size of object incorrect in collection::get2().", 00858 gsl_efailed); 00859 } 00860 op=(bool **)(pit->second.data); 00861 sz=pit->second.size; 00862 sz2=pit->second.size2; 00863 return gsl_success; 00864 } 00865 } 00866 // 1/9/05 We choose not to set an error here in case 00867 // the user is legitimately looking for something 00868 // that they don't expect to find. 00869 // O2SCL_ERR(tname+" not found in get().",not_found); 00870 return gsl_enotfound; 00871 } 00872 00873 /// Desc 00874 int getc(std::string name, char *&op, size_t &sz) { 00875 op=0; 00876 piter pit=plist.find(name); 00877 if (pit!=plist.end()) { 00878 if (((std::string)pit->second.iop->type())=="char") { 00879 if (pit->second.size==0 || pit->second.size2!=0) { 00880 O2SCL_ERR_RET("Size of object incorrect in collection::get2().", 00881 gsl_efailed); 00882 } 00883 op=(char *)(pit->second.data); 00884 sz=pit->second.size; 00885 return gsl_success; 00886 } 00887 } 00888 // 1/9/05 We choose not to set an error here in case 00889 // the user is legitimately looking for something 00890 // that they don't expect to find. 00891 // O2SCL_ERR(tname+" not found in get().",not_found); 00892 return gsl_enotfound; 00893 } 00894 00895 /// Desc 00896 int getc(std::string name, char **&op, size_t &sz, 00897 size_t &sz2) { 00898 op=0; 00899 piter pit=plist.find(name); 00900 if (pit!=plist.end()) { 00901 if (((std::string)pit->second.iop->type())=="char") { 00902 if (pit->second.size==0 || pit->second.size2==0) { 00903 O2SCL_ERR_RET("Size of object incorrect in collection::get2().", 00904 gsl_efailed); 00905 } 00906 op=(char **)(pit->second.data); 00907 sz=pit->second.size; 00908 sz2=pit->second.size2; 00909 return gsl_success; 00910 } 00911 } 00912 // 1/9/05 We choose not to set an error here in case 00913 // the user is legitimately looking for something 00914 // that they don't expect to find. 00915 // O2SCL_ERR(tname+" not found in get().",not_found); 00916 return gsl_enotfound; 00917 } 00918 00919 /// Desc 00920 int getd(std::string name, double *&op, size_t &sz) { 00921 op=0; 00922 piter pit=plist.find(name); 00923 if (pit!=plist.end()) { 00924 if (((std::string)pit->second.iop->type())=="double") { 00925 if (pit->second.size==0 || pit->second.size2!=0) { 00926 O2SCL_ERR_RET("Size of object incorrect in collection::get2().", 00927 gsl_efailed); 00928 } 00929 op=(double *)(pit->second.data); 00930 sz=pit->second.size; 00931 return gsl_success; 00932 } 00933 } 00934 // 1/9/05 We choose not to set an error here in case 00935 // the user is legitimately looking for something 00936 // that they don't expect to find. 00937 // O2SCL_ERR(tname+" not found in get().",not_found); 00938 return gsl_enotfound; 00939 } 00940 00941 /// Desc 00942 int getd(std::string name, double **&op, size_t &sz, 00943 size_t &sz2) { 00944 op=0; 00945 piter pit=plist.find(name); 00946 if (pit!=plist.end()) { 00947 if (((std::string)pit->second.iop->type())=="double") { 00948 if (pit->second.size==0 || pit->second.size2==0) { 00949 O2SCL_ERR_RET("Size of object incorrect in collection::get2().", 00950 gsl_efailed); 00951 } 00952 op=(double **)(pit->second.data); 00953 sz=pit->second.size; 00954 sz2=pit->second.size2; 00955 return gsl_success; 00956 } 00957 } 00958 // 1/9/05 We choose not to set an error here in case 00959 // the user is legitimately looking for something 00960 // that they don't expect to find. 00961 // O2SCL_ERR(tname+" not found in get().",not_found); 00962 return gsl_enotfound; 00963 } 00964 00965 /// Desc 00966 int geti(std::string name, int *&op, size_t &sz) { 00967 op=0; 00968 piter pit=plist.find(name); 00969 if (pit!=plist.end()) { 00970 if (((std::string)pit->second.iop->type())=="int") { 00971 if (pit->second.size==0 || pit->second.size2!=0) { 00972 O2SCL_ERR_RET("Size of object incorrect in collection::get2().", 00973 gsl_efailed); 00974 } 00975 op=(int *)(pit->second.data); 00976 sz=pit->second.size; 00977 return gsl_success; 00978 } 00979 } 00980 // 1/9/05 We choose not to set an error here in case 00981 // the user is legitimately looking for something 00982 // that they don't expect to find. 00983 // O2SCL_ERR(tname+" not found in get().",not_found); 00984 return gsl_enotfound; 00985 } 00986 00987 /// Desc 00988 int geti(std::string name, int **&op, size_t &sz, 00989 size_t &sz2) { 00990 op=0; 00991 piter pit=plist.find(name); 00992 if (pit!=plist.end()) { 00993 if (((std::string)pit->second.iop->type())=="int") { 00994 if (pit->second.size==0 || pit->second.size2==0) { 00995 O2SCL_ERR_RET("Size of object incorrect in collection::get2().", 00996 gsl_efailed); 00997 } 00998 op=(int **)(pit->second.data); 00999 sz=pit->second.size; 01000 sz2=pit->second.size2; 01001 return gsl_success; 01002 } 01003 } 01004 // 1/9/05 We choose not to set an error here in case 01005 // the user is legitimately looking for something 01006 // that they don't expect to find. 01007 // O2SCL_ERR(tname+" not found in get().",not_found); 01008 return gsl_enotfound; 01009 } 01010 01011 /// Desc 01012 int gets(std::string name, std::string *&op, size_t &sz) { 01013 op=0; 01014 piter pit=plist.find(name); 01015 if (pit!=plist.end()) { 01016 if (((std::string)pit->second.iop->type())=="string") { 01017 if (pit->second.size==0 || pit->second.size2!=0) { 01018 O2SCL_ERR_RET("Size of object incorrect in collection::get2().", 01019 gsl_efailed); 01020 } 01021 op=(std::string *)(pit->second.data); 01022 sz=pit->second.size; 01023 return gsl_success; 01024 } 01025 } 01026 // 1/9/05 We choose not to set an error here in case 01027 // the user is legitimately looking for something 01028 // that they don't expect to find. 01029 // O2SCL_ERR(tname+" not found in get().",not_found); 01030 return gsl_enotfound; 01031 } 01032 01033 /// Desc 01034 int gets(std::string name, std::string **&op, size_t &sz, 01035 size_t &sz2) { 01036 op=0; 01037 piter pit=plist.find(name); 01038 if (pit!=plist.end()) { 01039 if (((std::string)pit->second.iop->type())=="string") { 01040 if (pit->second.size==0 || pit->second.size2==0) { 01041 O2SCL_ERR_RET("Size of object incorrect in collection::get2().", 01042 gsl_efailed); 01043 } 01044 op=(std::string **)(pit->second.data); 01045 sz=pit->second.size; 01046 sz2=pit->second.size2; 01047 return gsl_success; 01048 } 01049 } 01050 // 1/9/05 We choose not to set an error here in case 01051 // the user is legitimately looking for something 01052 // that they don't expect to find. 01053 // O2SCL_ERR(tname+" not found in get().",not_found); 01054 return gsl_enotfound; 01055 } 01056 01057 /// Desc 01058 int getw(std::string name, std::string *&op, size_t &sz) { 01059 op=0; 01060 piter pit=plist.find(name); 01061 if (pit!=plist.end()) { 01062 if (((std::string)pit->second.iop->type())=="word") { 01063 if (pit->second.size==0 || pit->second.size2!=0) { 01064 O2SCL_ERR_RET("Size of object incorrect in collection::get2().", 01065 gsl_efailed); 01066 } 01067 op=(std::string *)(pit->second.data); 01068 sz=pit->second.size; 01069 return gsl_success; 01070 } 01071 } 01072 // 1/9/05 We choose not to set an error here in case 01073 // the user is legitimately looking for something 01074 // that they don't expect to find. 01075 // O2SCL_ERR(tname+" not found in get().",not_found); 01076 return gsl_enotfound; 01077 } 01078 01079 /// Desc 01080 int getw(std::string name, std::string **&op, size_t &sz, 01081 size_t &sz2) { 01082 op=0; 01083 piter pit=plist.find(name); 01084 if (pit!=plist.end()) { 01085 if (((std::string)pit->second.iop->type())=="word") { 01086 if (pit->second.size==0 || pit->second.size2==0) { 01087 O2SCL_ERR_RET("Size of object incorrect in collection::get2().", 01088 gsl_efailed); 01089 } 01090 op=(std::string **)(pit->second.data); 01091 sz=pit->second.size; 01092 sz2=pit->second.size2; 01093 return gsl_success; 01094 } 01095 } 01096 // 1/9/05 We choose not to set an error here in case 01097 // the user is legitimately looking for something 01098 // that they don't expect to find. 01099 // O2SCL_ERR(tname+" not found in get().",not_found); 01100 return gsl_enotfound; 01101 } 01102 01103 //@} 01104 01105 /// \name Generic type get methods 01106 //@{ 01107 01108 /// Desc 01109 template<class obj_t> 01110 int get(std::string name, obj_t *&op) { 01111 obj_t od; 01112 op=0; 01113 piter pit=plist.find(name); 01114 if (pit!=plist.end()) { 01115 if (((std::string)pit->second.iop->type())==od.type()) { 01116 if (pit->second.size!=0 || pit->second.size2!=0) { 01117 O2SCL_ERR_RET("Size of object incorrect in collection::get2().", 01118 gsl_efailed); 01119 } 01120 op=(obj_t *)(pit->second.data); 01121 return gsl_success; 01122 } 01123 } 01124 // 1/9/05 We choose not to set an error here in case 01125 // the user is legitimately looking for something 01126 // that they don't expect to find. 01127 // O2SCL_ERR(tname+" not found in get().",not_found); 01128 return gsl_enotfound; 01129 } 01130 01131 /// Desc 01132 template<class obj_t> 01133 int get(std::string name, obj_t *&op, size_t &sz) { 01134 obj_t od; 01135 op=0; 01136 piter pit=plist.find(name); 01137 if (pit!=plist.end()) { 01138 if (((std::string)pit->second.iop->type())==od.type()) { 01139 if (pit->second.size==0 || pit->second.size2!=0) { 01140 O2SCL_ERR_RET("Size of object incorrect in collection::get2().", 01141 gsl_efailed); 01142 } 01143 op=(obj_t *)(pit->second.data); 01144 sz=pit->second.size; 01145 return gsl_success; 01146 } 01147 } 01148 // 1/9/05 We choose not to set an error here in case 01149 // the user is legitimately looking for something 01150 // that they don't expect to find. 01151 // O2SCL_ERR(tname+" not found in get().",not_found); 01152 return gsl_enotfound; 01153 } 01154 01155 /// Desc 01156 template<class obj_t> 01157 int get(std::string name, obj_t **&op, size_t &sz, 01158 size_t &sz2) { 01159 obj_t od; 01160 op=0; 01161 piter pit=plist.find(name); 01162 if (pit!=plist.end()) { 01163 if (((std::string)pit->second.iop->type())==od.type()) { 01164 if (pit->second.size==0 || pit->second.size2==0) { 01165 O2SCL_ERR_RET("Size of object incorrect in collection::get2().", 01166 gsl_efailed); 01167 } 01168 op=(obj_t **)(pit->second.data); 01169 sz=pit->second.size; 01170 sz2=pit->second.size2; 01171 return gsl_success; 01172 } 01173 } 01174 // 1/9/05 We choose not to set an error here in case 01175 // the user is legitimately looking for something 01176 // that they don't expect to find. 01177 // O2SCL_ERR(tname+" not found in get().",not_found); 01178 return gsl_enotfound; 01179 } 01180 01181 01182 /** 01183 \brief Get an object 01184 01185 This should be deprecated, but is presently used in cli.cpp 01186 */ 01187 int get_void(std::string tname, void *&vec); 01188 //@} 01189 01190 /** \brief Return true if there is a parameter in the collection 01191 with the name \c tname 01192 */ 01193 int is_parameter(std::string tname) { 01194 piter pit=plist.find(tname); 01195 if (pit!=plist.end()) { 01196 return true; 01197 } 01198 return false; 01199 } 01200 01201 /// \name Text file get and set methods 01202 //@{ 01203 /// Output object of type \c stype and name \c name to output \c tof 01204 int get_type(text_out_file &tof, std::string stype, std::string name); 01205 01206 /// Output object with name \c name to output \c tof 01207 int get(text_out_file &tof, std::string &stype, std::string name); 01208 01209 /// Set object named \c name with input from \c tif 01210 int set(std::string name, text_in_file &tif, bool err_on_notfound=true); 01211 01212 /// Set object named \c name with input from \c val 01213 int set(std::string name, std::string val, bool err_on_notfound=true); 01214 //@} 01215 01216 /** \name Input and output of individual objects */ 01217 //@{ 01218 /** 01219 \brief Output one object to a file 01220 01221 This does not disturb any objects in the collection. The 01222 pointer specified does not need to be in the collection and 01223 is not added to the collection. 01224 */ 01225 int out_one(out_file_format *outs, std::string stype, std::string name, 01226 void *vp, int sz=0, int sz2=0); 01227 01228 /** 01229 \brief Output one object to a file 01230 01231 This does not disturb any objects in the collection. The 01232 pointer specified does not need to be in the collection and 01233 is not added to the collection. 01234 */ 01235 int out_one(std::string fname, std::string stype, std::string name, 01236 void *vp, int sz=0, int sz2=0); 01237 01238 //@} 01239 01240 /** 01241 \brief An iterator for stepping through a collection 01242 */ 01243 class iterator { 01244 01245 #ifndef DOXYGEN_INTERNAL 01246 01247 protected: 01248 01249 friend class collection; 01250 01251 /// Create an iterator from the STL iterator 01252 iterator(piter p) { pit=p; } 01253 01254 /// Local storage for the STL iterator 01255 piter pit; 01256 01257 #endif 01258 01259 public: 01260 01261 /// Prefix increment 01262 iterator operator++() { 01263 pit++; 01264 return *this; 01265 } 01266 01267 /// Postfix increment 01268 iterator operator++(int unused) { 01269 pit++; 01270 return *this; 01271 } 01272 01273 /// Prefix decrement 01274 iterator operator--() { 01275 pit--; 01276 return *this; 01277 } 01278 01279 /// Dereference 01280 collection_entry *operator->() const { 01281 return &(pit->second); 01282 }; 01283 01284 /// Return the name of the collection entry 01285 std::string name() { 01286 return pit->first; 01287 } 01288 01289 friend int operator==(const iterator &i1, const iterator &i2); 01290 01291 friend int operator!=(const iterator &i1, const iterator &i2); 01292 01293 }; 01294 01295 /** 01296 \brief An iterator for stepping through the entries 01297 in a collection of a particular type 01298 */ 01299 class type_iterator { 01300 01301 #ifndef DOXYGEN_INTERNAL 01302 01303 protected: 01304 01305 friend class collection; 01306 01307 /// Local storage for the type 01308 std::string ltype; 01309 01310 /// Store a pointer to the collection 01311 collection *lcop; 01312 01313 /// Constructor 01314 type_iterator(piter p, std::string type, collection *cop) { 01315 pit=p; 01316 ltype=type; 01317 lcop=cop; 01318 while (pit!=lcop->plist.end() && 01319 pit->second.iop->type()!=ltype) pit++; 01320 } 01321 01322 /// The STL iterator 01323 piter pit; 01324 01325 #endif 01326 01327 public: 01328 01329 /// Prefix increment 01330 type_iterator operator++() { 01331 if (pit!=lcop->plist.end()) pit++; 01332 while (pit!=lcop->plist.end() && 01333 pit->second.iop->type()!=ltype) pit++; 01334 return *this; 01335 } 01336 01337 /// Postfix increment 01338 type_iterator operator++(int unused) { 01339 if (pit!=lcop->plist.end()) pit++; 01340 while (pit!=lcop->plist.end() && 01341 pit->second.iop->type()!=ltype) pit++; 01342 return *this; 01343 } 01344 01345 /// Dereference 01346 collection_entry *operator->() const { 01347 return &(pit->second); 01348 }; 01349 01350 /// Return the name of the collection entry 01351 std::string name() { 01352 return pit->first; 01353 } 01354 01355 friend int operator==(const type_iterator &i1, const type_iterator &i2); 01356 01357 friend int operator!=(const type_iterator &i1, const type_iterator &i2); 01358 01359 }; 01360 01361 /** \name Iterator functions 01362 */ 01363 //@{ 01364 /// Return an iterator to the start of the collection 01365 iterator begin() { 01366 return iterator(plist.begin()); 01367 } 01368 01369 /// Return an iterator to the end of the collection 01370 iterator end() { 01371 return iterator(plist.end()); 01372 } 01373 01374 /** \brief Return an iterator to the first element of type \c utype 01375 in the collection 01376 */ 01377 type_iterator begin(std::string utype) { 01378 return type_iterator(plist.begin(),utype,this); 01379 } 01380 01381 /// Return an iterator to the end of the collection 01382 type_iterator end(std::string utype) { 01383 return type_iterator(plist.end(),utype,this); 01384 } 01385 //@} 01386 01387 }; 01388 01389 // ---------------------------------------------------------------- 01390 // End of class collection 01391 // ---------------------------------------------------------------- 01392 01393 /// Equality comparison for two iterators 01394 int operator==(const collection::iterator &i1, 01395 const collection::iterator &i2); 01396 01397 /// Inequality comparison for two iterators 01398 int operator!=(const collection::iterator &i1, 01399 const collection::iterator &i2); 01400 01401 /// Equality comparison for two iterators 01402 int operator==(const collection::type_iterator &i1, 01403 const collection::type_iterator &i2); 01404 01405 /// Inequality comparison for two iterators 01406 int operator!=(const collection::type_iterator &i1, 01407 const collection::type_iterator &i2); 01408 01409 /** 01410 \brief Class to control object input 01411 01412 This class is experimental. 01413 */ 01414 class cinput { 01415 01416 public: 01417 01418 /// Input an object 01419 int object_in(std::string type, in_file_format *ins, void *vp, 01420 std::string &name); 01421 01422 /// Input an array of objects 01423 int object_in(std::string type, in_file_format *ins, void *vp, 01424 int sz, std::string &name); 01425 01426 /// Input a 2-d array of objects 01427 int object_in(std::string type, in_file_format *ins, void *vp, 01428 int sz, int sz2, std::string &name); 01429 01430 /// Input an object, allocating memory first 01431 int object_in_mem(std::string type, in_file_format *ins, void *&vp, 01432 std::string &name); 01433 01434 /// Input an array of objects, allocating memory first 01435 int object_in_mem(std::string type, in_file_format *ins, void *&vp, 01436 int &sz, std::string &name); 01437 01438 /// Input a 2-d array of objects, allocating memory first 01439 int object_in_mem(std::string type, in_file_format *ins, void *&vp, 01440 int &sz, int &sz2, std::string &name); 01441 01442 #ifndef DOXYGEN_INTERNAL 01443 01444 protected: 01445 01446 /// Create a new input object for a collection 01447 cinput(collection *co) { 01448 cop=co; 01449 } 01450 01451 friend class collection; 01452 friend class io_base; 01453 01454 /// The pointers that need to be set 01455 std::vector<pointer_input> input_ptrs; 01456 01457 /// An iterator for the input pointers 01458 typedef std::vector<pointer_input>::iterator ipiter; 01459 01460 /// Assign all of the pointers read with the appropriate objects 01461 int assign_pointers(collection *co); 01462 01463 /// The pointer to the collection stored in the constructor 01464 collection *cop; 01465 01466 #endif 01467 01468 }; 01469 01470 /** 01471 \brief Class to control object output 01472 01473 This class is experimental. 01474 */ 01475 class coutput { 01476 01477 public: 01478 01479 /// Output an object 01480 int object_out(std::string type, out_file_format *outs, 01481 void *op, int sz=0, int sz2=0, std::string name=""); 01482 01483 #ifndef DOXYGEN_INTERNAL 01484 01485 protected: 01486 01487 friend class collection; 01488 friend class io_base; 01489 01490 /// Create a new object from a pointer to a collection 01491 coutput(class collection *co) { 01492 cop=co; 01493 npointers=0; 01494 }; 01495 01496 /// Order the pointers by numeric value 01497 struct ltptr { 01498 /// Returns \f$ p_1 < p_2 \f$ 01499 bool operator()(const void *p1, const void *p2) const { 01500 return p1<p2; 01501 } 01502 }; 01503 01504 /// The list pointers to object to be written to the file 01505 std::map<void *,pointer_output,ltptr> ptr_map; 01506 01507 /// A convenient iterator for the pointer list 01508 typedef std::map<void *,pointer_output,ltptr>::iterator pmiter; 01509 01510 /** 01511 \brief Look for an object in the collection given a pointer 01512 01513 Lookup the pointer \c vp in the collection, and return 01514 its name and collection_entry 01515 */ 01516 int pointer_lookup(void *vp, std::string &name, collection_entry *&ep); 01517 01518 /// The pointer to the collection stored in the constructor 01519 collection *cop; 01520 01521 /// Output all of the remaining pointers to 'out' 01522 int pointer_map_fout(out_file_format *out); 01523 01524 /** 01525 \brief Keep track of the number of pointers added to ptr_map 01526 01527 These are counted for the purposes of making a unique name. 01528 This is initialized 01529 in fout() and incremented in io_base::pointer_out 01530 */ 01531 int npointers; 01532 01533 #endif 01534 01535 }; 01536 01537 /** 01538 \brief A template for adding I/O classes 01539 01540 This class is experimental. 01541 */ 01542 template <class object> class io_vtlate : public io_base { 01543 01544 public: 01545 01546 /** 01547 \name Functions to be overloaded 01548 01549 These functions should be overloaded in all descendants of 01550 io_tlate. 01551 */ 01552 //@{ 01553 01554 /** \brief The name of the type to be processed */ 01555 virtual const char *type() { return "io_tlate"; } 01556 01557 /** \brief Method for reading an object from \c ins */ 01558 virtual int input(cinput *cin, in_file_format *ins, object *op) 01559 { return 0; } 01560 01561 /** 01562 \brief Method for writing an object to \c outs 01563 */ 01564 virtual int output(coutput *cout, out_file_format *outs, object *op) 01565 { return 0; } 01566 //@} 01567 01568 /** 01569 \name Functions to be overloaded for static data 01570 01571 These functions should be overloaded in all descendants of 01572 io_tlate which control I/O for classes which contain static 01573 data. 01574 */ 01575 //@{ 01576 01577 /** \brief \c true if the object contains static I/O data */ 01578 virtual bool has_static_data() { return false; } 01579 01580 /** \brief Method for reading static data for an object 01581 from \c ins 01582 01583 One must be careful about objects which set the static data in 01584 their constructors. An object is automatically created in order 01585 to read its static data. This means that if the static data is 01586 set in the constructor, then possibly useful information will be 01587 overwritten through the creation of this temporary object. 01588 01589 If one needs to set static data in the constructor of a 01590 singleton object, then the create() and remove() functions 01591 should be empty and a separate pointer to the singleton should 01592 be provided instead of void *vp. 01593 01594 This is only used if has_static_data() returns true; 01595 */ 01596 virtual int stat_input(cinput *cin, in_file_format *ins, object *op) 01597 { return 0; } 01598 01599 /** \brief Method for writing static data for an object 01600 to \c outs 01601 */ 01602 virtual int stat_output(coutput *cout, out_file_format *outs, 01603 object *op) 01604 { return 0; } 01605 //@} 01606 }; 01607 01608 /** \brief A template for adding I/O classes 01609 01610 This class is experimental. 01611 01612 Note that the generic interface here only works with 01613 pointers, not with the actual objects themselves. This 01614 is important, because it avoids the problem of I/O 01615 for an object with private copy and assigment operators. 01616 For basic types (bool, char, double, int, etc.), 01617 some additional add() and get() functions are defined. 01618 */ 01619 template <class object> class io_tlate : public io_base { 01620 01621 public: 01622 01623 /// Create an I/O class for type \c object. 01624 io_tlate() : io_base() {}; 01625 01626 #ifdef O2SCL_NEVER_DEFINED 01627 // This is just to assist emacs tabification 01628 } 01629 { 01630 #endif 01631 01632 /** 01633 \brief Create an I/O class for type \c object only if another 01634 object of type \c t is not yet present 01635 */ 01636 io_tlate(const char *t) : io_base(t) {}; 01637 01638 #ifdef O2SCL_NEVER_DEFINED 01639 // This is just to assist emacs tabification 01640 } 01641 { 01642 #endif 01643 01644 /** 01645 \name Functions to be overloaded 01646 01647 These functions should be overloaded in all descendants of 01648 io_tlate. 01649 */ 01650 //@{ 01651 01652 /** \brief The name of the type to be processed */ 01653 virtual const char *type() { return "io_tlate"; } 01654 01655 /** \brief Method for reading an object from \c ins */ 01656 virtual int input(cinput *cin, in_file_format *ins, object *op) 01657 { return 0; } 01658 01659 /** \brief Method for writing an object to \c outs */ 01660 virtual int output(coutput *cout, out_file_format *outs, object *op) 01661 { return 0; } 01662 //@} 01663 01664 /** 01665 \name Functions to be overloaded for static data 01666 01667 These functions should be overloaded in all descendants of 01668 io_tlate which control I/O for classes which contain static 01669 data. 01670 */ 01671 //@{ 01672 01673 /** \brief \c true if the object contains static I/O data */ 01674 virtual bool has_static_data() { return false; } 01675 01676 /** \brief Method for reading static data for an object 01677 from \c ins 01678 01679 One must be careful about objects which set the static data in 01680 their constructors. An object is automatically created in order 01681 to read its static data. This means that if the static data is 01682 set in the constructor, then possibly useful information will be 01683 overwritten through the creation of this temporary object. 01684 01685 If one needs to set static data in the constructor of a 01686 singleton object, then the create() and remove() functions 01687 should be empty and a separate pointer to the singleton should 01688 be provided instead of void *vp. 01689 01690 This is only used if has_static_data() returns true; 01691 */ 01692 virtual int stat_input(cinput *cin, in_file_format *ins, object *op) 01693 { return 0; } 01694 01695 /** \brief Method for writing static data for an object 01696 to \c outs 01697 */ 01698 virtual int stat_output(coutput *cout, out_file_format *outs, 01699 object *op) 01700 { return 0; } 01701 //@} 01702 01703 #ifndef DOXYGEN_INTERNAL 01704 01705 protected: 01706 01707 /// Desc 01708 virtual int object_in_void(cinput *cin, in_file_format *ins, void *op, 01709 std::string &name) { 01710 return object_in(cin,ins,(object *)op,name); 01711 } 01712 01713 /// Desc 01714 virtual int object_in_void(cinput *cin, in_file_format *ins, void *op, 01715 int sz, std::string &name) { 01716 return object_in(cin,ins,(object *)op,sz,name); 01717 } 01718 01719 /// Desc 01720 virtual int object_in_void(cinput *cin, in_file_format *ins, void *op, 01721 int sz, int sz2, std::string &name) { 01722 return object_in(cin,ins,(object **)op,sz,sz2,name); 01723 } 01724 01725 /// Desc 01726 virtual int object_in_mem_void(cinput *cin, in_file_format *ins, 01727 void *&vp, std::string &name) { 01728 object *op; 01729 int ret=object_in_mem(cin,ins,op,name); 01730 vp=(void *)op; 01731 return ret; 01732 } 01733 01734 /// Desc 01735 virtual int object_in_mem_void(cinput *cin, in_file_format *ins, void *&vp, 01736 int &sz,std::string &name) { 01737 object *op; 01738 int ret=object_in_mem(cin,ins,op,sz,name); 01739 vp=(void *)op; 01740 return ret; 01741 } 01742 01743 /// Desc 01744 virtual int object_in_mem_void(cinput *cin, in_file_format *ins, void *&vp, 01745 int &sz, int &sz2, std::string &name) { 01746 object **op; 01747 int ret=object_in_mem(cin,ins,op,sz,sz2,name); 01748 vp=(void *)op; 01749 return ret; 01750 } 01751 01752 /// Desc 01753 virtual int object_out_void(coutput *cout, out_file_format *outs, 01754 void *op, int sz=0, int sz2=0, 01755 std::string name="") { 01756 if (sz2==0) { 01757 return object_out(cout,outs,(object *)op,sz,name); 01758 } 01759 return object_out(cout,outs,(object **)op,sz,sz2,name); 01760 } 01761 01762 /// Desc 01763 virtual int stat_in_noobj(cinput *cin, in_file_format *ins) { 01764 int ret; 01765 object *op=new object; 01766 ret=stat_input(cin,ins,op); 01767 return ret; 01768 }; 01769 01770 /// Desc 01771 virtual int stat_out_noobj(coutput *cout, out_file_format *outs) { 01772 int ret; 01773 object *op=new object; 01774 ret=stat_output(cout,outs,op); 01775 return ret; 01776 }; 01777 01778 /// Desc 01779 int in_wrapper(cinput *cin, in_file_format *ins, void *&vp) { 01780 object *op; 01781 if (vp==0) { 01782 op=new object; 01783 } else { 01784 op=(object *)vp; 01785 } 01786 input(cin,ins,op); 01787 if (vp==0) vp=(void *)op; 01788 return 0; 01789 } 01790 01791 /// Desc 01792 int in_wrapper(cinput *cin, in_file_format *ins, void *&vp, int &sz) { 01793 object *op; 01794 ins->int_in(sz); 01795 if (vp==0) { 01796 op=new object[sz]; 01797 } else { 01798 op=(object *)vp; 01799 } 01800 for(int i=0;i<sz;i++) { 01801 input(cin,ins,&(op[i])); 01802 } 01803 if (vp==0) vp=(void *)op; 01804 return 0; 01805 } 01806 01807 /// Desc 01808 int in_wrapper(cinput *cin, in_file_format *ins, void *&vp, int &sz, 01809 int &sz2) { 01810 object **op; 01811 ins->int_in(sz); 01812 ins->int_in(sz2); 01813 if (vp==0) { 01814 op=new object *[sz]; 01815 } else { 01816 op=(object **)vp; 01817 } 01818 for(int i=0;i<sz;i++) { 01819 if (vp==0) op[i]=new object[sz2]; 01820 for(int j=0;j<sz2;j++) { 01821 input(cin,ins,&(op[i][j])); 01822 } 01823 } 01824 if (vp==0) vp=(void *)op; 01825 return 0; 01826 } 01827 01828 /// Desc 01829 int out_wrapper(coutput *cout, out_file_format *outs, void *vp, int sz, 01830 int sz2) { 01831 int i, j; 01832 std::string stype; 01833 object *op=(object *)vp; 01834 01835 if (sz==0 && sz2==0) { 01836 output(cout,outs,op); 01837 } else if (sz2==0) { 01838 outs->int_out(sz); 01839 for(i=0;i<sz;i++) { 01840 output(cout,outs,&(op[i])); 01841 } 01842 } else { 01843 object **aop=(object **)vp; 01844 outs->int_out(sz); 01845 outs->int_out(sz2); 01846 for(i=0;i<sz;i++) { 01847 for(j=0;j<sz2;j++) { 01848 output(cout,outs,&(aop[i][j])); 01849 } 01850 } 01851 } 01852 return 0; 01853 } 01854 01855 /// Remove the memory for an object 01856 virtual int remove(void *vp) { 01857 object *op=(object *)vp; 01858 delete op; 01859 return 0; 01860 } 01861 01862 /// Remove the memory for an array of objects 01863 virtual int remove_arr(void *vp) { 01864 object *op=(object *)vp; 01865 delete[] op; 01866 return 0; 01867 } 01868 01869 /// Remove the memory for a 2-dimensional array of objects 01870 virtual int remove_2darr(void *vp, int sz) { 01871 object **op=(object **)vp; 01872 for(int i=0;i<sz;i++) { 01873 delete[] op[i]; 01874 } 01875 delete[] op; 01876 return 0; 01877 } 01878 01879 /// Static input for an object 01880 virtual int stat_in_wrapper(cinput *cin, in_file_format *ins, void *vp) { 01881 object *op=(object *)vp; 01882 stat_input(cin,ins,op); 01883 return 0; 01884 } 01885 01886 /// Static output for an object 01887 virtual int stat_out_wrapper(coutput *cout, out_file_format *outs, 01888 void *vp) { 01889 object *op=(object *)vp; 01890 outs->start_object(type()); 01891 stat_output(cout,outs,op); 01892 outs->end_object(); 01893 return 0; 01894 } 01895 01896 #endif 01897 01898 public: 01899 01900 /// \name Input functions 01901 //@{ 01902 /** \brief Read an object from \c ins */ 01903 virtual int object_in(cinput *cin, in_file_format *ins, object *op, 01904 std::string &name) { 01905 std::string typ; 01906 ins->start_object(typ,name); 01907 input(cin,ins,op); 01908 ins->end_object(); 01909 return 0; 01910 } 01911 01912 /** \brief Read an array of objects from \c ins */ 01913 virtual int object_in(cinput *cin, in_file_format *ins, object *op, 01914 int sz, std::string &name) { 01915 int i; 01916 01917 std::string typ; 01918 ins->start_object(typ,name); 01919 ins->int_in(sz); 01920 for(i=0;i<sz;i++) { 01921 input(cin,ins,&op[i]); 01922 } 01923 ins->end_object(); 01924 return 0; 01925 } 01926 01927 /** \brief Read a 2-d array of objects from \c ins */ 01928 virtual int object_in(cinput *cin, in_file_format *ins, object **op, 01929 int sz, int sz2, std::string &name) { 01930 int i, j; 01931 01932 std::string typ; 01933 ins->start_object(typ,name); 01934 ins->int_in(sz); 01935 ins->int_in(sz2); 01936 01937 for(i=0;i<sz;i++) { 01938 object *opx=op[i]; 01939 for(j=0;j<sz2;j++) { 01940 input(cin,ins,&opx[j]); 01941 } 01942 } 01943 ins->end_object(); 01944 return 0; 01945 } 01946 01947 #ifdef O2SCL_NEVER_DEFINED 01948 01949 /** \brief Create memory for a 2-d array of objects 01950 and read it from \c ins 01951 */ 01952 template<size_t N> 01953 int object_in(cinput *co, in_file_format *ins, 01954 object op[][N], int sz, std::string &name) { 01955 int i, j; 01956 01957 std::string typ; 01958 ins->start_object(typ,name); 01959 ins->int_in(sz); 01960 ins->int_in(((int)N)); 01961 01962 for(i=0;i<sz;i++) { 01963 for(j=0;j<N;j++) { 01964 input(co,ins,&op[i][j]); 01965 } 01966 } 01967 ins->end_object(); 01968 01969 return 0; 01970 } 01971 01972 #endif 01973 01974 /** \brief Create memory for an object and read it from \c ins */ 01975 virtual int object_in_mem(cinput *cin, in_file_format *ins, 01976 object *&op, std::string &name) { 01977 op=new object; 01978 std::string typ; 01979 ins->start_object(typ,name); 01980 input(cin,ins,op); 01981 ins->end_object(); 01982 return 0; 01983 } 01984 01985 /** \brief Create memory for an object and read it from \c ins */ 01986 virtual int object_in_mem(cinput *cin, in_file_format *ins, object *&op, 01987 int &sz, std::string &name) { 01988 int i; 01989 01990 std::string typ; 01991 ins->start_object(typ,name); 01992 ins->int_in(sz); 01993 op=new object[sz]; 01994 for(i=0;i<sz;i++) { 01995 input(cin,ins,&op[i]); 01996 } 01997 ins->end_object(); 01998 return 0; 01999 } 02000 02001 /** \brief Create memory for an object and read it from \c ins */ 02002 virtual int object_in_mem(cinput *cin, in_file_format *ins, 02003 object **&op, int &sz, int &sz2, 02004 std::string &name) { 02005 int i, j; 02006 02007 std::string typ; 02008 ins->start_object(typ,name); 02009 ins->int_in(sz); 02010 ins->int_in(sz2); 02011 02012 op=new object *[sz]; 02013 for(i=0;i<sz;i++) { 02014 op[i]=new object[sz2]; 02015 for(j=0;j<sz2;j++) { 02016 input(cin,ins,&op[i][j]); 02017 } 02018 } 02019 ins->end_object(); 02020 02021 return 0; 02022 } 02023 02024 #ifdef O2SCL_NEVER_DEFINED 02025 02026 /** \brief Create memory for a 2-d array of objects 02027 and read it from \c ins 02028 02029 Note that you must specify in advance the size \c N. 02030 */ 02031 template<size_t N> 02032 int object_in_mem(cinput *co, in_file_format *ins, 02033 object op[][N], int &sz, std::string &name) { 02034 int i, j; 02035 02036 std::string typ; 02037 ins->start_object(typ,name); 02038 ins->int_in(sz); 02039 ins->int_in(((int)N)); 02040 02041 // commented out on 3/10/05 - i don't think this should be here 02042 // op=new object *[sz]; 02043 for(i=0;i<sz;i++) { 02044 // commented out on 3/10/05 - i don't think this should be here 02045 // op[i]=new object[N]; 02046 for(j=0;j<N;j++) { 02047 input(co,ins,&op[i][j]); 02048 } 02049 } 02050 ins->end_object(); 02051 02052 return 0; 02053 } 02054 02055 #endif 02056 02057 //@} 02058 02059 /// \name Output functions 02060 //@{ 02061 /** \brief Output an object (or an array of objects) to \c outs */ 02062 virtual int object_out(coutput *cout, out_file_format *outs, object *op, 02063 int sz=0, std::string name="") { 02064 if (sz==0) { 02065 outs->start_object(type(),name); 02066 output(cout,outs,op); 02067 } else { 02068 outs->start_object(((std::string)(type()))+"[]",name); 02069 outs->int_out(sz); 02070 for(int i=0;i<sz;i++) { 02071 output(cout,outs,&op[i]); 02072 } 02073 } 02074 outs->end_object(); 02075 return 0; 02076 } 02077 02078 /** \brief Output an object (or an array of objects) to \c outs 02079 */ 02080 virtual int object_out(coutput *cout, out_file_format *outs, object **op, 02081 int sz, int sz2, std::string name="") { 02082 int i, j; 02083 02084 outs->start_object(((std::string)(type()))+"[][]",name); 02085 outs->int_out(sz); 02086 outs->int_out(sz2); 02087 for(i=0;i<sz;i++) { 02088 for(j=0;j<sz2;j++) { 02089 output(cout,outs,&(op[i][j])); 02090 } 02091 } 02092 outs->end_object(); 02093 return 0; 02094 } 02095 02096 #ifdef O2SCL_NEVER_DEFINED 02097 02098 /** \brief Output a 2-d array of objects to \c outs 02099 */ 02100 template<size_t N> 02101 int object_out(coutput *cout, out_file_format *outs, 02102 object op[][N], int sz, std::string name="") { 02103 int i, j; 02104 02105 outs->start_object(((std::string)(type()))+"[][]",name); 02106 outs->int_out(sz); 02107 outs->int_out(N); 02108 for(i=0;i<sz;i++) { 02109 for(j=0;j<N;j++) { 02110 output(cout,outs,&op[i][j]); 02111 } 02112 } 02113 outs->end_object(); 02114 return 0; 02115 } 02116 02117 #endif 02118 02119 //@} 02120 02121 /** \name Memory allocation 02122 */ 02123 //@{ 02124 /** \brief Create memory for an object */ 02125 virtual int mem_alloc(object *&op) { 02126 op=new object; 02127 return 0; 02128 } 02129 02130 /** \brief Create memory for an object */ 02131 virtual int mem_alloc_arr(object *&op, int sz) { 02132 op=new object[sz]; 02133 return 0; 02134 } 02135 02136 /** \brief Create memory for an object */ 02137 virtual int mem_alloc_2darr(object **&op, int sz, int sz2) { 02138 op=new object *[sz]; 02139 for(int i=0;i<sz;i++) { 02140 op[i]=new object[sz2]; 02141 } 02142 return 0; 02143 } 02144 //@} 02145 02146 /** \name Add and get objects from a collection 02147 */ 02148 //@{ 02149 02150 /** \brief Add an object(s) to a collection */ 02151 int add(collection &coll, std::string name, object *op, int sz=0, 02152 bool overwrt=true, bool owner=false) { 02153 return coll.add_void(name,this,op,sz,0,overwrt,owner); 02154 } 02155 02156 /** \brief Add an object(s) to a collection */ 02157 int add_2darray(collection &coll, std::string name, object **op, 02158 int sz, int sz2, bool overwrt=true, 02159 bool owner=false) { 02160 return coll.add_void(name,this,op,sz,sz2,overwrt,owner); 02161 } 02162 02163 #ifdef O2SCL_NEVER_DEFINED 02164 02165 /** \brief Get an object(s) from a collection */ 02166 int get(collection &coll, std::string tname, object *&op) { 02167 void *vp; 02168 int ret=coll.get(tname,vp); 02169 if (ret==0) { 02170 op=(object *)vp; 02171 } else { 02172 op=0; 02173 return ret; 02174 } 02175 return 0; 02176 } 02177 02178 /** \brief Get an object(s) from a collection */ 02179 int get(collection &co, std::string tname, object *&op, int &sz) { 02180 void *vp; 02181 int ret=co.get(tname,vp,sz); 02182 if (ret==0) { 02183 op=(object *)vp; 02184 } else { 02185 op=0; 02186 return ret; 02187 } 02188 return 0; 02189 } 02190 02191 /** \brief Get an object(s) from a collection */ 02192 int get(collection &co, std::string tname, object **&op, int &sz, 02193 int &sz2) { 02194 void *vp; 02195 int ret=co.get(tname,vp,sz,sz2); 02196 if (ret==0) { 02197 op=(object **)vp; 02198 } else { 02199 op=0; 02200 return ret; 02201 } 02202 return 0; 02203 } 02204 #endif 02205 //@} 02206 02207 /** \name Other functions 02208 */ 02209 //@{ 02210 02211 /// Free the memory associated with an object 02212 virtual int mem_free(object *op) { return remove((void *)op); } 02213 02214 /// Free the memory associated with an array of objects 02215 virtual int mem_free_arr(object *op) 02216 { return remove_arr((void *)op); } 02217 02218 /// Free the memory associated with a 2-d array of objects 02219 virtual int mem_free_2darr(object **op, int sz) 02220 { return remove_2darr((void *)op,sz); } 02221 02222 //@} 02223 02224 }; 02225 02226 template<> int io_tlate<bool>::input 02227 (cinput *co, in_file_format *ins, bool *dp); 02228 template<> int io_tlate<bool>::output 02229 (coutput *co, out_file_format *outs, bool *dp); 02230 template<> const char *io_tlate<bool>::type(); 02231 02232 /** 02233 \brief I/O object for bool variables 02234 02235 This class is experimental. 02236 */ 02237 #ifdef DOXYGENP 02238 class bool_io_type : public io_tlate<object> 02239 #else 02240 class bool_io_type : public io_tlate<bool> 02241 #endif 02242 { 02243 public: 02244 02245 /// Desc 02246 bool_io_type(const char *t) : io_tlate<bool>(t) {}; 02247 02248 bool_io_type() : io_tlate<bool>() {}; 02249 02250 }; 02251 02252 template<> int io_tlate<char>::input 02253 (cinput *co, in_file_format *ins, char *dp); 02254 template<> int io_tlate<char>::output 02255 (coutput *co, out_file_format *outs, char *dp); 02256 template<> const char *io_tlate<char>::type(); 02257 02258 /** 02259 \brief I/O object for char variables 02260 02261 This class is experimental. 02262 */ 02263 #ifdef DOXYGENP 02264 class char_io_type : public io_tlate<object> 02265 #else 02266 class char_io_type : public io_tlate<char> 02267 #endif 02268 { 02269 public: 02270 /// Desc 02271 char_io_type(const char *t) : io_tlate<char>(t) {}; 02272 02273 char_io_type() : io_tlate<char>() {}; 02274 02275 }; 02276 02277 template<> int io_tlate<double>::input 02278 (cinput *co, in_file_format *ins, double *dp); 02279 template<> int io_tlate<double>::output 02280 (coutput *co, out_file_format *outs, double *dp); 02281 template<> const char *io_tlate<double>::type(); 02282 02283 /** 02284 \brief I/O object for double variables 02285 02286 This class is experimental. 02287 */ 02288 #ifdef DOXYGENP 02289 class double_io_type : public io_tlate<object> 02290 #else 02291 class double_io_type : public io_tlate<double> 02292 #endif 02293 { 02294 public: 02295 /// Desc 02296 double_io_type(const char *t) : io_tlate<double>(t) {}; 02297 02298 double_io_type() : io_tlate<double>() {}; 02299 02300 }; 02301 02302 template<> int io_tlate<int>::input 02303 (cinput *co, in_file_format *ins, int *dp); 02304 template<> int io_tlate<int>::output 02305 (coutput *co, out_file_format *outs, int *dp); 02306 template<> const char *io_tlate<int>::type(); 02307 02308 /** 02309 \brief I/O object for int variables 02310 02311 This class is experimental. 02312 */ 02313 #ifdef DOXYGENP 02314 class int_io_type : public io_tlate<object> 02315 #else 02316 class int_io_type : public io_tlate<int> 02317 #endif 02318 { 02319 public: 02320 /// Desc 02321 int_io_type(const char *t) : io_tlate<int>(t) {}; 02322 02323 int_io_type() : io_tlate<int>() {}; 02324 02325 }; 02326 02327 template<> int io_tlate<unsigned long int>::input 02328 (cinput *co, in_file_format *ins, unsigned long int *dp); 02329 template<> int io_tlate<unsigned long int>::output 02330 (coutput *co, out_file_format *outs, unsigned long int *dp); 02331 template<> const char *io_tlate<unsigned long int>::type(); 02332 02333 /** 02334 \brief I/O object for long variables 02335 02336 This class is experimental. 02337 */ 02338 #ifdef DOXYGENP 02339 class long_io_type : public io_tlate<object> 02340 #else 02341 class long_io_type : public io_tlate<unsigned long int> 02342 #endif 02343 { 02344 public: 02345 /// Desc 02346 long_io_type(const char *t) : io_tlate<unsigned long int>(t) {}; 02347 02348 long_io_type() : io_tlate<unsigned long int>() {}; 02349 02350 }; 02351 02352 template<> int io_tlate<std::string>::input 02353 (cinput *co, in_file_format *ins, std::string *dp); 02354 template<> int io_tlate<std::string>::output 02355 (coutput *co, out_file_format *outs, std::string *dp); 02356 template<> const char *io_tlate<std::string>::type(); 02357 02358 /** 02359 \brief I/O object for string variables 02360 02361 This class is experimental. 02362 */ 02363 #ifdef DOXYGENP 02364 class string_io_type : public io_tlate<object> 02365 #else 02366 class string_io_type : public io_tlate<std::string> 02367 #endif 02368 { 02369 public: 02370 /// Desc 02371 string_io_type(const char *t) : io_tlate<std::string>(t) {}; 02372 02373 string_io_type() : io_tlate<std::string>() {}; 02374 02375 }; 02376 02377 /** 02378 \brief I/O object for words 02379 02380 This class is experimental. 02381 */ 02382 #ifdef DOXYGENP 02383 class word_io_type : public io_tlate<object> 02384 #else 02385 class word_io_type : public io_tlate<std::string> 02386 #endif 02387 { 02388 public: 02389 /// Desc 02390 word_io_type(const char *t) : io_tlate<std::string>(t) {}; 02391 02392 word_io_type() : io_tlate<std::string>() {}; 02393 02394 /// Desc 02395 int input(cinput *co, in_file_format *ins, std::string *dp); 02396 /// Desc 02397 int output(coutput *co, out_file_format *outs, std::string *dp); 02398 02399 /// Desc 02400 const char *type() { return "word"; } 02401 }; 02402 02403 #ifdef O2SCL_NEVER_DEFINED 02404 /** 02405 \brief I/O for ovector 02406 */ 02407 template<> int io_tlate<ovector>::input 02408 (cinput *co, in_file_format *ins, ovector *dp); 02409 template<> int io_tlate<ovector>::output 02410 (coutput *co, out_file_format *outs, ovector *dp); 02411 template<> const char *io_tlate<ovector>::type(); 02412 02413 /** 02414 \brief I/O for omatrix 02415 */ 02416 template<> int io_tlate<omatrix>::input 02417 (cinput *co, in_file_format *ins, omatrix *dp); 02418 template<> int io_tlate<omatrix>::output 02419 (coutput *co, out_file_format *outs, omatrix *dp); 02420 template<> const char *io_tlate<omatrix>::type(); 02421 02422 /** 02423 \brief I/O for ovector_int 02424 */ 02425 template<> int io_tlate<ovector_int>::input 02426 (cinput *co, in_file_format *ins, ovector_int *dp); 02427 template<> int io_tlate<ovector_int>::output 02428 (coutput *co, out_file_format *outs, ovector_int *dp); 02429 template<> const char *io_tlate<ovector_int>::type(); 02430 02431 /** 02432 \brief I/O for omatrix_int 02433 */ 02434 template<> int io_tlate<omatrix_int>::input 02435 (cinput *co, in_file_format *ins, omatrix_int *dp); 02436 template<> int io_tlate<omatrix_int>::output 02437 (coutput *co, out_file_format *outs, omatrix_int *dp); 02438 template<> const char *io_tlate<omatrix_int>::type(); 02439 02440 /** 02441 \brief I/O for ovector_cx 02442 */ 02443 template<> int io_tlate<ovector_cx>::input 02444 (cinput *co, in_file_format *ins, ovector_cx *dp); 02445 template<> int io_tlate<ovector_cx>::output 02446 (coutput *co, out_file_format *outs, ovector_cx *dp); 02447 template<> const char *io_tlate<ovector_cx>::type(); 02448 02449 /** 02450 \brief I/O for omatrix_cx 02451 */ 02452 template<> int io_tlate<omatrix_cx>::input 02453 (cinput *co, in_file_format *ins, omatrix_cx *dp); 02454 template<> int io_tlate<omatrix_cx>::output 02455 (coutput *co, out_file_format *outs, omatrix_cx *dp); 02456 template<> const char *io_tlate<omatrix_cx>::type(); 02457 02458 typedef io_tlate<ovector> ovector_io_type; 02459 typedef io_tlate<omatrix> omatrix_io_type; 02460 typedef io_tlate<ovector_int> ovector_int_io_type; 02461 typedef io_tlate<omatrix_int> omatrix_int_io_type; 02462 typedef io_tlate<ovector_cx> ovector_cx_io_type; 02463 typedef io_tlate<omatrix_cx> omatrix_cx_io_type; 02464 02465 #endif 02466 02467 #ifndef DOXYGENP 02468 } 02469 #endif 02470 02471 #endif
Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.
Project hosting provided by
,
O2scl Sourceforge Project Page