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 NULL, 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 \brief Get an object 01183 01184 This should be deprecated, but is presently used in cli.cpp 01185 */ 01186 int get_void(std::string tname, void *&vec); 01187 //@} 01188 01189 /// \name Text file get and set methods 01190 //@{ 01191 /// Output object of type \c stype and name \c name to output \c tof 01192 int get_type(text_out_file &tof, std::string stype, std::string name); 01193 01194 /// Output object with name \c name to output \c tof 01195 int get(text_out_file &tof, std::string &stype, std::string name); 01196 01197 /// Set object named \c name with input from \c tif 01198 int set(std::string name, text_in_file &tif); 01199 01200 /// Set object named \c name with input from \c val 01201 int set(std::string name, std::string val); 01202 //@} 01203 01204 /** \name Input and output of individual objects */ 01205 //@{ 01206 /** 01207 \brief Output one object to a file 01208 01209 This does not disturb any objects in the collection. The 01210 pointer specified does not need to be in the collection and 01211 is not added to the collection. 01212 */ 01213 int out_one(out_file_format *outs, std::string stype, std::string name, 01214 void *vp, int sz=0, int sz2=0); 01215 01216 /** 01217 \brief Output one object to a file 01218 01219 This does not disturb any objects in the collection. The 01220 pointer specified does not need to be in the collection and 01221 is not added to the collection. 01222 */ 01223 int out_one(std::string fname, std::string stype, std::string name, 01224 void *vp, int sz=0, int sz2=0); 01225 01226 //@} 01227 01228 /** 01229 \brief An iterator for stepping through a collection 01230 */ 01231 class iterator { 01232 01233 #ifndef DOXYGEN_INTERNAL 01234 01235 protected: 01236 01237 friend class collection; 01238 01239 /// Create an iterator from the STL iterator 01240 iterator(piter p) { pit=p; } 01241 01242 /// Local storage for the STL iterator 01243 piter pit; 01244 01245 #endif 01246 01247 public: 01248 01249 /// Prefix increment 01250 iterator operator++() { 01251 pit++; 01252 return *this; 01253 } 01254 01255 /// Postfix increment 01256 iterator operator++(int unused) { 01257 pit++; 01258 return *this; 01259 } 01260 01261 /// Prefix decrement 01262 iterator operator--() { 01263 pit--; 01264 return *this; 01265 } 01266 01267 /// Dereference 01268 collection_entry *operator->() const { 01269 return &(pit->second); 01270 }; 01271 01272 /// Return the name of the collection entry 01273 std::string name() { 01274 return pit->first; 01275 } 01276 01277 friend int operator==(const iterator &i1, const iterator &i2); 01278 01279 friend int operator!=(const iterator &i1, const iterator &i2); 01280 01281 }; 01282 01283 /** 01284 \brief An iterator for stepping through the entries 01285 in a collection of a particular type 01286 */ 01287 class type_iterator { 01288 01289 #ifndef DOXYGEN_INTERNAL 01290 01291 protected: 01292 01293 friend class collection; 01294 01295 /// Local storage for the type 01296 std::string ltype; 01297 01298 /// Store a pointer to the collection 01299 collection *lcop; 01300 01301 /// Constructor 01302 type_iterator(piter p, std::string type, collection *cop) { 01303 pit=p; 01304 ltype=type; 01305 lcop=cop; 01306 while (pit!=lcop->plist.end() && 01307 pit->second.iop->type()!=ltype) pit++; 01308 } 01309 01310 /// The STL iterator 01311 piter pit; 01312 01313 #endif 01314 01315 public: 01316 01317 /// Prefix increment 01318 type_iterator operator++() { 01319 if (pit!=lcop->plist.end()) pit++; 01320 while (pit!=lcop->plist.end() && 01321 pit->second.iop->type()!=ltype) pit++; 01322 return *this; 01323 } 01324 01325 /// Postfix increment 01326 type_iterator operator++(int unused) { 01327 if (pit!=lcop->plist.end()) pit++; 01328 while (pit!=lcop->plist.end() && 01329 pit->second.iop->type()!=ltype) pit++; 01330 return *this; 01331 } 01332 01333 /// Dereference 01334 collection_entry *operator->() const { 01335 return &(pit->second); 01336 }; 01337 01338 /// Return the name of the collection entry 01339 std::string name() { 01340 return pit->first; 01341 } 01342 01343 friend int operator==(const type_iterator &i1, const type_iterator &i2); 01344 01345 friend int operator!=(const type_iterator &i1, const type_iterator &i2); 01346 01347 }; 01348 01349 /** \name Iterator functions 01350 */ 01351 //@{ 01352 /// Return an iterator to the start of the collection 01353 iterator begin() { 01354 return iterator(plist.begin()); 01355 } 01356 01357 /// Return an iterator to the end of the collection 01358 iterator end() { 01359 return iterator(plist.end()); 01360 } 01361 01362 /** \brief Return an iterator to the first element of type \c utype 01363 in the collection 01364 */ 01365 type_iterator begin(std::string utype) { 01366 return type_iterator(plist.begin(),utype,this); 01367 } 01368 01369 /// Return an iterator to the end of the collection 01370 type_iterator end(std::string utype) { 01371 return type_iterator(plist.end(),utype,this); 01372 } 01373 //@} 01374 01375 }; 01376 01377 // ---------------------------------------------------------------- 01378 // End of class collection 01379 // ---------------------------------------------------------------- 01380 01381 /// Equality comparison for two iterators 01382 int operator==(const collection::iterator &i1, 01383 const collection::iterator &i2); 01384 01385 /// Inequality comparison for two iterators 01386 int operator!=(const collection::iterator &i1, 01387 const collection::iterator &i2); 01388 01389 /// Equality comparison for two iterators 01390 int operator==(const collection::type_iterator &i1, 01391 const collection::type_iterator &i2); 01392 01393 /// Inequality comparison for two iterators 01394 int operator!=(const collection::type_iterator &i1, 01395 const collection::type_iterator &i2); 01396 01397 /** 01398 \brief Class to control object input 01399 01400 This class is experimental. 01401 */ 01402 class cinput { 01403 01404 public: 01405 01406 /// Input an object 01407 int object_in(std::string type, in_file_format *ins, void *vp, 01408 std::string &name); 01409 01410 /// Input an array of objects 01411 int object_in(std::string type, in_file_format *ins, void *vp, 01412 int sz, std::string &name); 01413 01414 /// Input a 2-d array of objects 01415 int object_in(std::string type, in_file_format *ins, void *vp, 01416 int sz, int sz2, std::string &name); 01417 01418 /// Input an object, allocating memory first 01419 int object_in_mem(std::string type, in_file_format *ins, void *&vp, 01420 std::string &name); 01421 01422 /// Input an array of objects, allocating memory first 01423 int object_in_mem(std::string type, in_file_format *ins, void *&vp, 01424 int &sz, std::string &name); 01425 01426 /// Input a 2-d array of objects, allocating memory first 01427 int object_in_mem(std::string type, in_file_format *ins, void *&vp, 01428 int &sz, int &sz2, std::string &name); 01429 01430 #ifndef DOXYGEN_INTERNAL 01431 01432 protected: 01433 01434 /// Create a new input object for a collection 01435 cinput(collection *co) { 01436 cop=co; 01437 } 01438 01439 friend class collection; 01440 friend class io_base; 01441 01442 /// The pointers that need to be set 01443 std::vector<pointer_input> input_ptrs; 01444 01445 /// An iterator for the input pointers 01446 typedef std::vector<pointer_input>::iterator ipiter; 01447 01448 /// Assign all of the pointers read with the appropriate objects 01449 int assign_pointers(collection *co); 01450 01451 /// The pointer to the collection stored in the constructor 01452 collection *cop; 01453 01454 #endif 01455 01456 }; 01457 01458 /** 01459 \brief Class to control object output 01460 01461 This class is experimental. 01462 */ 01463 class coutput { 01464 01465 public: 01466 01467 /// Output an object 01468 int object_out(std::string type, out_file_format *outs, 01469 void *op, int sz=0, int sz2=0, std::string name=""); 01470 01471 #ifndef DOXYGEN_INTERNAL 01472 01473 protected: 01474 01475 friend class collection; 01476 friend class io_base; 01477 01478 /// Create a new object from a pointer to a collection 01479 coutput(class collection *co) { 01480 cop=co; 01481 npointers=0; 01482 }; 01483 01484 /// Order the pointers by numeric value 01485 struct ltptr { 01486 /// Returns \f$ p_1 < p_2 \f$ 01487 bool operator()(const void *p1, const void *p2) const { 01488 return p1<p2; 01489 } 01490 }; 01491 01492 /// The list pointers to object to be written to the file 01493 std::map<void *,pointer_output,ltptr> ptr_map; 01494 01495 /// A convenient iterator for the pointer list 01496 typedef std::map<void *,pointer_output,ltptr>::iterator pmiter; 01497 01498 /** 01499 \brief Look for an object in the collection given a pointer 01500 01501 Lookup the pointer \c vp in the collection, and return 01502 its name and collection_entry 01503 */ 01504 int pointer_lookup(void *vp, std::string &name, collection_entry *&ep); 01505 01506 /// The pointer to the collection stored in the constructor 01507 collection *cop; 01508 01509 /// Output all of the remaining pointers to 'out' 01510 int pointer_map_fout(out_file_format *out); 01511 01512 /** 01513 \brief Keep track of the number of pointers added to ptr_map 01514 01515 These are counted for the purposes of making a unique name. 01516 This is initialized 01517 in fout() and incremented in io_base::pointer_out 01518 */ 01519 int npointers; 01520 01521 #endif 01522 01523 }; 01524 01525 /** 01526 \brief A template for adding I/O classes 01527 01528 This class is experimental. 01529 */ 01530 template <class object> class io_vtlate : public io_base { 01531 01532 public: 01533 01534 /** 01535 \name Functions to be overloaded 01536 01537 These functions should be overloaded in all descendants of 01538 io_tlate. 01539 */ 01540 //@{ 01541 01542 /** \brief The name of the type to be processed */ 01543 virtual const char *type() { return "io_tlate"; } 01544 01545 /** \brief Method for reading an object from \c ins */ 01546 virtual int input(cinput *cin, in_file_format *ins, object *op) 01547 { return 0; } 01548 01549 /** 01550 \brief Method for writing an object to \c outs 01551 */ 01552 virtual int output(coutput *cout, out_file_format *outs, object *op) 01553 { return 0; } 01554 //@} 01555 01556 /** 01557 \name Functions to be overloaded for static data 01558 01559 These functions should be overloaded in all descendants of 01560 io_tlate which control I/O for classes which contain static 01561 data. 01562 */ 01563 //@{ 01564 01565 /** \brief \c true if the object contains static I/O data */ 01566 virtual bool has_static_data() { return false; } 01567 01568 /** \brief Method for reading static data for an object 01569 from \c ins 01570 01571 One must be careful about objects which set the static data in 01572 their constructors. An object is automatically created in order 01573 to read its static data. This means that if the static data is 01574 set in the constructor, then possibly useful information will be 01575 overwritten through the creation of this temporary object. 01576 01577 If one needs to set static data in the constructor of a 01578 singleton object, then the create() and remove() functions 01579 should be empty and a separate pointer to the singleton should 01580 be provided instead of void *vp. 01581 01582 This is only used if has_static_data() returns true; 01583 */ 01584 virtual int stat_input(cinput *cin, in_file_format *ins, object *op) 01585 { return 0; } 01586 01587 /** \brief Method for writing static data for an object 01588 to \c outs 01589 */ 01590 virtual int stat_output(coutput *cout, out_file_format *outs, 01591 object *op) 01592 { return 0; } 01593 //@} 01594 }; 01595 01596 /** \brief A template for adding I/O classes 01597 01598 This class is experimental. 01599 01600 Note that the generic interface here only works with 01601 pointers, not with the actual objects themselves. This 01602 is important, because it avoids the problem of I/O 01603 for an object with private copy and assigment operators. 01604 For basic types (bool, char, double, int, etc.), 01605 some additional add() and get() functions are defined. 01606 */ 01607 template <class object> class io_tlate : public io_base { 01608 01609 public: 01610 01611 /// Create an I/O class for type \c object. 01612 io_tlate() : io_base() {}; 01613 01614 #ifdef O2SCL_NEVER_DEFINED 01615 // This is just to assist emacs tabification 01616 } 01617 { 01618 #endif 01619 01620 /** 01621 \brief Create an I/O class for type \c object only if another 01622 object of type \c t is not yet present 01623 */ 01624 io_tlate(const char *t) : io_base(t) {}; 01625 01626 #ifdef O2SCL_NEVER_DEFINED 01627 // This is just to assist emacs tabification 01628 } 01629 { 01630 #endif 01631 01632 /** 01633 \name Functions to be overloaded 01634 01635 These functions should be overloaded in all descendants of 01636 io_tlate. 01637 */ 01638 //@{ 01639 01640 /** \brief The name of the type to be processed */ 01641 virtual const char *type() { return "io_tlate"; } 01642 01643 /** \brief Method for reading an object from \c ins */ 01644 virtual int input(cinput *cin, in_file_format *ins, object *op) 01645 { return 0; } 01646 01647 /** \brief Method for writing an object to \c outs */ 01648 virtual int output(coutput *cout, out_file_format *outs, object *op) 01649 { return 0; } 01650 //@} 01651 01652 /** 01653 \name Functions to be overloaded for static data 01654 01655 These functions should be overloaded in all descendants of 01656 io_tlate which control I/O for classes which contain static 01657 data. 01658 */ 01659 //@{ 01660 01661 /** \brief \c true if the object contains static I/O data */ 01662 virtual bool has_static_data() { return false; } 01663 01664 /** \brief Method for reading static data for an object 01665 from \c ins 01666 01667 One must be careful about objects which set the static data in 01668 their constructors. An object is automatically created in order 01669 to read its static data. This means that if the static data is 01670 set in the constructor, then possibly useful information will be 01671 overwritten through the creation of this temporary object. 01672 01673 If one needs to set static data in the constructor of a 01674 singleton object, then the create() and remove() functions 01675 should be empty and a separate pointer to the singleton should 01676 be provided instead of void *vp. 01677 01678 This is only used if has_static_data() returns true; 01679 */ 01680 virtual int stat_input(cinput *cin, in_file_format *ins, object *op) 01681 { return 0; } 01682 01683 /** \brief Method for writing static data for an object 01684 to \c outs 01685 */ 01686 virtual int stat_output(coutput *cout, out_file_format *outs, 01687 object *op) 01688 { return 0; } 01689 //@} 01690 01691 #ifndef DOXYGEN_INTERNAL 01692 01693 protected: 01694 01695 /// Desc 01696 virtual int object_in_void(cinput *cin, in_file_format *ins, void *op, 01697 std::string &name) { 01698 return object_in(cin,ins,(object *)op,name); 01699 } 01700 01701 /// Desc 01702 virtual int object_in_void(cinput *cin, in_file_format *ins, void *op, 01703 int sz, std::string &name) { 01704 return object_in(cin,ins,(object *)op,sz,name); 01705 } 01706 01707 /// Desc 01708 virtual int object_in_void(cinput *cin, in_file_format *ins, void *op, 01709 int sz, int sz2, std::string &name) { 01710 return object_in(cin,ins,(object **)op,sz,sz2,name); 01711 } 01712 01713 /// Desc 01714 virtual int object_in_mem_void(cinput *cin, in_file_format *ins, 01715 void *&vp, std::string &name) { 01716 object *op; 01717 int ret=object_in_mem(cin,ins,op,name); 01718 vp=(void *)op; 01719 return ret; 01720 } 01721 01722 /// Desc 01723 virtual int object_in_mem_void(cinput *cin, in_file_format *ins, void *&vp, 01724 int &sz,std::string &name) { 01725 object *op; 01726 int ret=object_in_mem(cin,ins,op,sz,name); 01727 vp=(void *)op; 01728 return ret; 01729 } 01730 01731 /// Desc 01732 virtual int object_in_mem_void(cinput *cin, in_file_format *ins, void *&vp, 01733 int &sz, int &sz2, std::string &name) { 01734 object **op; 01735 int ret=object_in_mem(cin,ins,op,sz,sz2,name); 01736 vp=(void *)op; 01737 return ret; 01738 } 01739 01740 /// Desc 01741 virtual int object_out_void(coutput *cout, out_file_format *outs, 01742 void *op, int sz=0, int sz2=0, 01743 std::string name="") { 01744 if (sz2==0) { 01745 return object_out(cout,outs,(object *)op,sz,name); 01746 } 01747 return object_out(cout,outs,(object **)op,sz,sz2,name); 01748 } 01749 01750 /// Desc 01751 virtual int stat_in_noobj(cinput *cin, in_file_format *ins) { 01752 int ret; 01753 object *op=new object; 01754 ret=stat_input(cin,ins,op); 01755 return ret; 01756 }; 01757 01758 /// Desc 01759 virtual int stat_out_noobj(coutput *cout, out_file_format *outs) { 01760 int ret; 01761 object *op=new object; 01762 ret=stat_output(cout,outs,op); 01763 return ret; 01764 }; 01765 01766 /// Desc 01767 int in_wrapper(cinput *cin, in_file_format *ins, void *&vp) { 01768 object *op; 01769 if (vp==NULL) { 01770 op=new object; 01771 } else { 01772 op=(object *)vp; 01773 } 01774 input(cin,ins,op); 01775 if (vp==NULL) vp=(void *)op; 01776 return 0; 01777 } 01778 01779 /// Desc 01780 int in_wrapper(cinput *cin, in_file_format *ins, void *&vp, int &sz) { 01781 object *op; 01782 ins->int_in(sz); 01783 if (vp==NULL) { 01784 op=new object[sz]; 01785 } else { 01786 op=(object *)vp; 01787 } 01788 for(int i=0;i<sz;i++) { 01789 input(cin,ins,&(op[i])); 01790 } 01791 if (vp==NULL) vp=(void *)op; 01792 return 0; 01793 } 01794 01795 /// Desc 01796 int in_wrapper(cinput *cin, in_file_format *ins, void *&vp, int &sz, 01797 int &sz2) { 01798 object **op; 01799 ins->int_in(sz); 01800 ins->int_in(sz2); 01801 if (vp==NULL) { 01802 op=new object *[sz]; 01803 } else { 01804 op=(object **)vp; 01805 } 01806 for(int i=0;i<sz;i++) { 01807 if (vp==NULL) op[i]=new object[sz2]; 01808 for(int j=0;j<sz2;j++) { 01809 input(cin,ins,&(op[i][j])); 01810 } 01811 } 01812 if (vp==NULL) vp=(void *)op; 01813 return 0; 01814 } 01815 01816 /// Desc 01817 int out_wrapper(coutput *cout, out_file_format *outs, void *vp, int sz, 01818 int sz2) { 01819 int i, j; 01820 std::string stype; 01821 object *op=(object *)vp; 01822 01823 if (sz==0 && sz2==0) { 01824 output(cout,outs,op); 01825 } else if (sz2==0) { 01826 outs->int_out(sz); 01827 for(i=0;i<sz;i++) { 01828 output(cout,outs,&(op[i])); 01829 } 01830 } else { 01831 object **aop=(object **)vp; 01832 outs->int_out(sz); 01833 outs->int_out(sz2); 01834 for(i=0;i<sz;i++) { 01835 for(j=0;j<sz2;j++) { 01836 output(cout,outs,&(aop[i][j])); 01837 } 01838 } 01839 } 01840 return 0; 01841 } 01842 01843 /// Remove the memory for an object 01844 virtual int remove(void *vp) { 01845 object *op=(object *)vp; 01846 delete op; 01847 return 0; 01848 } 01849 01850 /// Remove the memory for an array of objects 01851 virtual int remove_arr(void *vp) { 01852 object *op=(object *)vp; 01853 delete[] op; 01854 return 0; 01855 } 01856 01857 /// Remove the memory for a 2-dimensional array of objects 01858 virtual int remove_2darr(void *vp, int sz) { 01859 object **op=(object **)vp; 01860 for(int i=0;i<sz;i++) { 01861 delete[] op[i]; 01862 } 01863 delete[] op; 01864 return 0; 01865 } 01866 01867 /// Static input for an object 01868 virtual int stat_in_wrapper(cinput *cin, in_file_format *ins, void *vp) { 01869 object *op=(object *)vp; 01870 stat_input(cin,ins,op); 01871 return 0; 01872 } 01873 01874 /// Static output for an object 01875 virtual int stat_out_wrapper(coutput *cout, out_file_format *outs, 01876 void *vp) { 01877 object *op=(object *)vp; 01878 outs->start_object(type()); 01879 stat_output(cout,outs,op); 01880 outs->end_object(); 01881 return 0; 01882 } 01883 01884 #endif 01885 01886 public: 01887 01888 /// \name Input functions 01889 //@{ 01890 /** \brief Read an object from \c ins */ 01891 virtual int object_in(cinput *cin, in_file_format *ins, object *op, 01892 std::string &name) { 01893 std::string typ; 01894 ins->start_object(typ,name); 01895 input(cin,ins,op); 01896 ins->end_object(); 01897 return 0; 01898 } 01899 01900 /** \brief Read an array of objects from \c ins */ 01901 virtual int object_in(cinput *cin, in_file_format *ins, object *op, 01902 int sz, std::string &name) { 01903 int i; 01904 01905 std::string typ; 01906 ins->start_object(typ,name); 01907 ins->int_in(sz); 01908 for(i=0;i<sz;i++) { 01909 input(cin,ins,&op[i]); 01910 } 01911 ins->end_object(); 01912 return 0; 01913 } 01914 01915 /** \brief Read a 2-d array of objects from \c ins */ 01916 virtual int object_in(cinput *cin, in_file_format *ins, object **op, 01917 int sz, int sz2, std::string &name) { 01918 int i, j; 01919 01920 std::string typ; 01921 ins->start_object(typ,name); 01922 ins->int_in(sz); 01923 ins->int_in(sz2); 01924 01925 for(i=0;i<sz;i++) { 01926 object *opx=op[i]; 01927 for(j=0;j<sz2;j++) { 01928 input(cin,ins,&opx[j]); 01929 } 01930 } 01931 ins->end_object(); 01932 return 0; 01933 } 01934 01935 /** \brief Create memory for a 2-d array of objects 01936 and read it from \c ins 01937 */ 01938 template<size_t N> 01939 int object_in(cinput *co, in_file_format *ins, 01940 object op[][N], int sz, std::string &name) { 01941 int i, j; 01942 01943 std::string typ; 01944 ins->start_object(typ,name); 01945 ins->int_in(sz); 01946 ins->int_in(((int)N)); 01947 01948 for(i=0;i<sz;i++) { 01949 for(j=0;j<N;j++) { 01950 input(co,ins,&op[i][j]); 01951 } 01952 } 01953 ins->end_object(); 01954 01955 return 0; 01956 } 01957 01958 /** \brief Create memory for an object and read it from \c ins */ 01959 virtual int object_in_mem(cinput *cin, in_file_format *ins, 01960 object *&op, std::string &name) { 01961 op=new object; 01962 std::string typ; 01963 ins->start_object(typ,name); 01964 input(cin,ins,op); 01965 ins->end_object(); 01966 return 0; 01967 } 01968 01969 /** \brief Create memory for an object and read it from \c ins */ 01970 virtual int object_in_mem(cinput *cin, in_file_format *ins, object *&op, 01971 int &sz, std::string &name) { 01972 int i; 01973 01974 std::string typ; 01975 ins->start_object(typ,name); 01976 ins->int_in(sz); 01977 op=new object[sz]; 01978 for(i=0;i<sz;i++) { 01979 input(cin,ins,&op[i]); 01980 } 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, 01987 object **&op, int &sz, int &sz2, 01988 std::string &name) { 01989 int i, j; 01990 01991 std::string typ; 01992 ins->start_object(typ,name); 01993 ins->int_in(sz); 01994 ins->int_in(sz2); 01995 01996 op=new object *[sz]; 01997 for(i=0;i<sz;i++) { 01998 op[i]=new object[sz2]; 01999 for(j=0;j<sz2;j++) { 02000 input(cin,ins,&op[i][j]); 02001 } 02002 } 02003 ins->end_object(); 02004 02005 return 0; 02006 } 02007 02008 /** \brief Create memory for a 2-d array of objects 02009 and read it from \c ins 02010 02011 Note that you must specify in advance the size \c N. 02012 */ 02013 template<size_t N> 02014 int object_in_mem(cinput *co, in_file_format *ins, 02015 object op[][N], int &sz, std::string &name) { 02016 int i, j; 02017 02018 std::string typ; 02019 ins->start_object(typ,name); 02020 ins->int_in(sz); 02021 ins->int_in(((int)N)); 02022 02023 // commented out on 3/10/05 - i don't think this should be here 02024 // op=new object *[sz]; 02025 for(i=0;i<sz;i++) { 02026 // commented out on 3/10/05 - i don't think this should be here 02027 // op[i]=new object[N]; 02028 for(j=0;j<N;j++) { 02029 input(co,ins,&op[i][j]); 02030 } 02031 } 02032 ins->end_object(); 02033 02034 return 0; 02035 } 02036 //@} 02037 02038 /// \name Output functions 02039 //@{ 02040 /** \brief Output an object (or an array of objects) to \c outs */ 02041 virtual int object_out(coutput *cout, out_file_format *outs, object *op, 02042 int sz=0, std::string name="") { 02043 if (sz==0) { 02044 outs->start_object(type(),name); 02045 output(cout,outs,op); 02046 } else { 02047 outs->start_object(((std::string)(type()))+"[]",name); 02048 outs->int_out(sz); 02049 for(int i=0;i<sz;i++) { 02050 output(cout,outs,&op[i]); 02051 } 02052 } 02053 outs->end_object(); 02054 return 0; 02055 } 02056 02057 /** \brief Output an object (or an array of objects) to \c outs 02058 */ 02059 virtual int object_out(coutput *cout, out_file_format *outs, object **op, 02060 int sz, int sz2, std::string name="") { 02061 int i, j; 02062 02063 outs->start_object(((std::string)(type()))+"[][]",name); 02064 outs->int_out(sz); 02065 outs->int_out(sz2); 02066 for(i=0;i<sz;i++) { 02067 for(j=0;j<sz2;j++) { 02068 output(cout,outs,&(op[i][j])); 02069 } 02070 } 02071 outs->end_object(); 02072 return 0; 02073 } 02074 02075 /** \brief Output a 2-d array of objects to \c outs 02076 */ 02077 template<size_t N> 02078 int object_out(coutput *cout, out_file_format *outs, 02079 object op[][N], int sz, std::string name="") { 02080 int i, j; 02081 02082 outs->start_object(((std::string)(type()))+"[][]",name); 02083 outs->int_out(sz); 02084 outs->int_out(N); 02085 for(i=0;i<sz;i++) { 02086 for(j=0;j<N;j++) { 02087 output(cout,outs,&op[i][j]); 02088 } 02089 } 02090 outs->end_object(); 02091 return 0; 02092 } 02093 //@} 02094 02095 /** \name Memory allocation 02096 */ 02097 //@{ 02098 /** \brief Create memory for an object */ 02099 virtual int mem_alloc(object *&op) { 02100 op=new object; 02101 return 0; 02102 } 02103 02104 /** \brief Create memory for an object */ 02105 virtual int mem_alloc_arr(object *&op, int sz) { 02106 op=new object[sz]; 02107 return 0; 02108 } 02109 02110 /** \brief Create memory for an object */ 02111 virtual int mem_alloc_2darr(object **&op, int sz, int sz2) { 02112 op=new object *[sz]; 02113 for(int i=0;i<sz;i++) { 02114 op[i]=new object[sz2]; 02115 } 02116 return 0; 02117 } 02118 //@} 02119 02120 /** \name Add and get objects from a collection 02121 */ 02122 //@{ 02123 02124 /** \brief Add an object(s) to a collection */ 02125 int add(collection &coll, std::string name, object *op, int sz=0, 02126 bool overwrt=true, bool owner=false) { 02127 return coll.add_void(name,this,op,sz,0,overwrt,owner); 02128 } 02129 02130 /** \brief Add an object(s) to a collection */ 02131 int add_2darray(collection &coll, std::string name, object **op, 02132 int sz, int sz2, bool overwrt=true, 02133 bool owner=false) { 02134 return coll.add_void(name,this,op,sz,sz2,overwrt,owner); 02135 } 02136 02137 #ifdef NEVER_DEFINED 02138 02139 /** \brief Get an object(s) from a collection */ 02140 int get(collection &coll, std::string tname, object *&op) { 02141 void *vp; 02142 int ret=coll.get(tname,vp); 02143 if (ret==0) { 02144 op=(object *)vp; 02145 } else { 02146 op=NULL; 02147 return ret; 02148 } 02149 return 0; 02150 } 02151 02152 /** \brief Get an object(s) from a collection */ 02153 int get(collection &co, std::string tname, object *&op, int &sz) { 02154 void *vp; 02155 int ret=co.get(tname,vp,sz); 02156 if (ret==0) { 02157 op=(object *)vp; 02158 } else { 02159 op=NULL; 02160 return ret; 02161 } 02162 return 0; 02163 } 02164 02165 /** \brief Get an object(s) from a collection */ 02166 int get(collection &co, std::string tname, object **&op, int &sz, 02167 int &sz2) { 02168 void *vp; 02169 int ret=co.get(tname,vp,sz,sz2); 02170 if (ret==0) { 02171 op=(object **)vp; 02172 } else { 02173 op=NULL; 02174 return ret; 02175 } 02176 return 0; 02177 } 02178 #endif 02179 //@} 02180 02181 /** \name Other functions 02182 */ 02183 //@{ 02184 02185 /// Free the memory associated with an object 02186 virtual int mem_free(object *op) { return remove((void *)op); } 02187 02188 /// Free the memory associated with an array of objects 02189 virtual int mem_free_arr(object *op) 02190 { return remove_arr((void *)op); } 02191 02192 /// Free the memory associated with a 2-d array of objects 02193 virtual int mem_free_2darr(object **op, int sz) 02194 { return remove_2darr((void *)op,sz); } 02195 02196 //@} 02197 02198 }; 02199 02200 template<> int io_tlate<bool>::input 02201 (cinput *co, in_file_format *ins, bool *dp); 02202 template<> int io_tlate<bool>::output 02203 (coutput *co, out_file_format *outs, bool *dp); 02204 template<> const char *io_tlate<bool>::type(); 02205 02206 /** 02207 \brief I/O object for bool variables 02208 02209 This class is experimental. 02210 */ 02211 #ifdef DOXYGENP 02212 class bool_io_type : public io_tlate<object> 02213 #else 02214 class bool_io_type : public io_tlate<bool> 02215 #endif 02216 { 02217 public: 02218 02219 /// Desc 02220 bool_io_type(const char *t) : io_tlate<bool>(t) {}; 02221 02222 bool_io_type() : io_tlate<bool>() {}; 02223 02224 }; 02225 02226 template<> int io_tlate<char>::input 02227 (cinput *co, in_file_format *ins, char *dp); 02228 template<> int io_tlate<char>::output 02229 (coutput *co, out_file_format *outs, char *dp); 02230 template<> const char *io_tlate<char>::type(); 02231 02232 /** 02233 \brief I/O object for char variables 02234 02235 This class is experimental. 02236 */ 02237 #ifdef DOXYGENP 02238 class char_io_type : public io_tlate<object> 02239 #else 02240 class char_io_type : public io_tlate<char> 02241 #endif 02242 { 02243 public: 02244 /// Desc 02245 char_io_type(const char *t) : io_tlate<char>(t) {}; 02246 02247 char_io_type() : io_tlate<char>() {}; 02248 02249 }; 02250 02251 template<> int io_tlate<double>::input 02252 (cinput *co, in_file_format *ins, double *dp); 02253 template<> int io_tlate<double>::output 02254 (coutput *co, out_file_format *outs, double *dp); 02255 template<> const char *io_tlate<double>::type(); 02256 02257 /** 02258 \brief I/O object for double variables 02259 02260 This class is experimental. 02261 */ 02262 #ifdef DOXYGENP 02263 class double_io_type : public io_tlate<object> 02264 #else 02265 class double_io_type : public io_tlate<double> 02266 #endif 02267 { 02268 public: 02269 /// Desc 02270 double_io_type(const char *t) : io_tlate<double>(t) {}; 02271 02272 double_io_type() : io_tlate<double>() {}; 02273 02274 }; 02275 02276 template<> int io_tlate<int>::input 02277 (cinput *co, in_file_format *ins, int *dp); 02278 template<> int io_tlate<int>::output 02279 (coutput *co, out_file_format *outs, int *dp); 02280 template<> const char *io_tlate<int>::type(); 02281 02282 /** 02283 \brief I/O object for int variables 02284 02285 This class is experimental. 02286 */ 02287 #ifdef DOXYGENP 02288 class int_io_type : public io_tlate<object> 02289 #else 02290 class int_io_type : public io_tlate<int> 02291 #endif 02292 { 02293 public: 02294 /// Desc 02295 int_io_type(const char *t) : io_tlate<int>(t) {}; 02296 02297 int_io_type() : io_tlate<int>() {}; 02298 02299 }; 02300 02301 template<> int io_tlate<unsigned long int>::input 02302 (cinput *co, in_file_format *ins, unsigned long int *dp); 02303 template<> int io_tlate<unsigned long int>::output 02304 (coutput *co, out_file_format *outs, unsigned long int *dp); 02305 template<> const char *io_tlate<unsigned long int>::type(); 02306 02307 /** 02308 \brief I/O object for long variables 02309 02310 This class is experimental. 02311 */ 02312 #ifdef DOXYGENP 02313 class long_io_type : public io_tlate<object> 02314 #else 02315 class long_io_type : public io_tlate<unsigned long int> 02316 #endif 02317 { 02318 public: 02319 /// Desc 02320 long_io_type(const char *t) : io_tlate<unsigned long int>(t) {}; 02321 02322 long_io_type() : io_tlate<unsigned long int>() {}; 02323 02324 }; 02325 02326 template<> int io_tlate<std::string>::input 02327 (cinput *co, in_file_format *ins, std::string *dp); 02328 template<> int io_tlate<std::string>::output 02329 (coutput *co, out_file_format *outs, std::string *dp); 02330 template<> const char *io_tlate<std::string>::type(); 02331 02332 /** 02333 \brief I/O object for string variables 02334 02335 This class is experimental. 02336 */ 02337 #ifdef DOXYGENP 02338 class string_io_type : public io_tlate<object> 02339 #else 02340 class string_io_type : public io_tlate<std::string> 02341 #endif 02342 { 02343 public: 02344 /// Desc 02345 string_io_type(const char *t) : io_tlate<std::string>(t) {}; 02346 02347 string_io_type() : io_tlate<std::string>() {}; 02348 02349 }; 02350 02351 /** 02352 \brief I/O object for words 02353 02354 This class is experimental. 02355 */ 02356 #ifdef DOXYGENP 02357 class word_io_type : public io_tlate<object> 02358 #else 02359 class word_io_type : public io_tlate<std::string> 02360 #endif 02361 { 02362 public: 02363 /// Desc 02364 word_io_type(const char *t) : io_tlate<std::string>(t) {}; 02365 02366 word_io_type() : io_tlate<std::string>() {}; 02367 02368 /// Desc 02369 int input(cinput *co, in_file_format *ins, std::string *dp); 02370 /// Desc 02371 int output(coutput *co, out_file_format *outs, std::string *dp); 02372 02373 /// Desc 02374 const char *type() { return "word"; } 02375 }; 02376 02377 #ifdef O2SCL_NEVER_DEFINED 02378 /** 02379 \brief I/O for ovector 02380 */ 02381 template<> int io_tlate<ovector>::input 02382 (cinput *co, in_file_format *ins, ovector *dp); 02383 template<> int io_tlate<ovector>::output 02384 (coutput *co, out_file_format *outs, ovector *dp); 02385 template<> const char *io_tlate<ovector>::type(); 02386 02387 /** 02388 \brief I/O for omatrix 02389 */ 02390 template<> int io_tlate<omatrix>::input 02391 (cinput *co, in_file_format *ins, omatrix *dp); 02392 template<> int io_tlate<omatrix>::output 02393 (coutput *co, out_file_format *outs, omatrix *dp); 02394 template<> const char *io_tlate<omatrix>::type(); 02395 02396 /** 02397 \brief I/O for ovector_int 02398 */ 02399 template<> int io_tlate<ovector_int>::input 02400 (cinput *co, in_file_format *ins, ovector_int *dp); 02401 template<> int io_tlate<ovector_int>::output 02402 (coutput *co, out_file_format *outs, ovector_int *dp); 02403 template<> const char *io_tlate<ovector_int>::type(); 02404 02405 /** 02406 \brief I/O for omatrix_int 02407 */ 02408 template<> int io_tlate<omatrix_int>::input 02409 (cinput *co, in_file_format *ins, omatrix_int *dp); 02410 template<> int io_tlate<omatrix_int>::output 02411 (coutput *co, out_file_format *outs, omatrix_int *dp); 02412 template<> const char *io_tlate<omatrix_int>::type(); 02413 02414 /** 02415 \brief I/O for ovector_cx 02416 */ 02417 template<> int io_tlate<ovector_cx>::input 02418 (cinput *co, in_file_format *ins, ovector_cx *dp); 02419 template<> int io_tlate<ovector_cx>::output 02420 (coutput *co, out_file_format *outs, ovector_cx *dp); 02421 template<> const char *io_tlate<ovector_cx>::type(); 02422 02423 /** 02424 \brief I/O for omatrix_cx 02425 */ 02426 template<> int io_tlate<omatrix_cx>::input 02427 (cinput *co, in_file_format *ins, omatrix_cx *dp); 02428 template<> int io_tlate<omatrix_cx>::output 02429 (coutput *co, out_file_format *outs, omatrix_cx *dp); 02430 template<> const char *io_tlate<omatrix_cx>::type(); 02431 02432 typedef io_tlate<ovector> ovector_io_type; 02433 typedef io_tlate<omatrix> omatrix_io_type; 02434 typedef io_tlate<ovector_int> ovector_int_io_type; 02435 typedef io_tlate<omatrix_int> omatrix_int_io_type; 02436 typedef io_tlate<ovector_cx> ovector_cx_io_type; 02437 typedef io_tlate<omatrix_cx> omatrix_cx_io_type; 02438 02439 #endif 02440 02441 #ifndef DOXYGENP 02442 } 02443 #endif 02444 02445 #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