00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 2008, 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 /* \file collection.h 00044 \brief Brief desc. 00045 */ 00046 00047 #ifndef DOXYGENP 00048 namespace o2scl { 00049 #endif 00050 00051 /// An entry in a collection 00052 typedef struct { 00053 /// The pointer to the object 00054 void *data; 00055 /// The first size parameter 00056 int size; 00057 /// The second size parameter 00058 int size2; 00059 /// True if the collection owns this object 00060 bool owner; 00061 /// A pointer to the corresponding \ref io_base object 00062 class io_base *iop; 00063 } collection_entry; 00064 00065 /// A pointer output structure 00066 typedef struct { 00067 /// The name of the pointer 00068 std::string name; 00069 /// Pointer to the collection entry 00070 collection_entry *ep; 00071 /// True if the pointer has been written to the file 00072 bool output; 00073 } pointer_output; 00074 00075 /// A pointer input structure 00076 typedef struct { 00077 /// The name of the pointer 00078 std::string name; 00079 /// The pointer 00080 void **ptr; 00081 /// The type of the object pointed to 00082 std::string stype; 00083 } pointer_input; 00084 00085 class cinput; 00086 class coutput; 00087 00088 /** 00089 \brief I/O base class 00090 00091 00092 00093 This class is necessary so that the collection method source code 00094 and the io_base method source code doesn't have to go in header files. 00095 00096 \todo Should the remove() functions be moved to class collection? 00097 */ 00098 class io_base { 00099 00100 #ifndef DOXYGEN_INTERNAL 00101 00102 protected: 00103 /// for io_type_info.add_type(). 00104 friend class io_type_info; 00105 00106 /// for stat_in and stat_out 00107 friend class collection; 00108 00109 friend class cinput; 00110 friend class coutput; 00111 friend class io_manager; 00112 00113 /// A pointer to the type manager 00114 static class io_manager *iom; 00115 00116 /// A count of the number of objects 00117 static int objs_count; 00118 00119 /// Automatically create an object for stat_in 00120 virtual int stat_in_noobj(cinput *co, in_file_format *ins); 00121 00122 /// Automatically create an object for stat_out 00123 virtual int stat_out_noobj(coutput *co, out_file_format *outs); 00124 00125 /** \brief Allocate memory and input an object 00126 */ 00127 virtual int in_wrapper(cinput *co, in_file_format *ins, void *&vp); 00128 00129 /** \brief Allocate memory and input an array of objects 00130 */ 00131 virtual int in_wrapper(cinput *co, in_file_format *ins, void *&vp, 00132 int &sz); 00133 00134 /** \brief Allocate memory and input a 2-d array of objects 00135 */ 00136 virtual int in_wrapper(cinput *co, in_file_format *ins, void *&vp, 00137 int &sz, int &sz2); 00138 00139 /** \brief Internal function to output an object (or an array 00140 or 2-d array) 00141 */ 00142 virtual int out_wrapper(coutput *co, out_file_format *outs, 00143 void *vp, int sz, int sz2); 00144 00145 /// Input an object (no memory allocation) 00146 virtual int object_in_void(cinput *cin, in_file_format *ins, void *op, 00147 std::string &name); 00148 00149 /// Input an array of objects (no memory allocation) 00150 virtual int object_in_void(cinput *cin, in_file_format *ins, void *op, 00151 int sz, std::string &name); 00152 00153 /// Input a 2-d array of objects (no memory allocation) 00154 virtual int object_in_void(cinput *cin, in_file_format *ins, void *op, 00155 int sz, int sz2, std::string &name); 00156 00157 /// Input an object (no memory allocation) 00158 virtual int object_in_mem_void(cinput *cin, in_file_format *ins, 00159 void *&op, std::string &name); 00160 00161 /// Input an array of objects (no memory allocation) 00162 virtual int object_in_mem_void(cinput *cin, in_file_format *ins, 00163 void *&op, int &sz, std::string &name); 00164 00165 /// Input a 2-d array of objects (no memory allocation) 00166 virtual int object_in_mem_void(cinput *cin, in_file_format *ins, 00167 void *&op, int &sz, int &sz2, 00168 std::string &name); 00169 00170 /// Output an object, an array of objects, or a 2-d array of objects 00171 virtual int object_out_void(coutput *cout, out_file_format *outs, 00172 void *op, int sz, int sz2, 00173 std::string name=""); 00174 00175 /** \brief Store the value of \c sw given in the constructor so 00176 that we know if we need to remove the type in the destructor 00177 */ 00178 int sw_store; 00179 00180 /** \name Functions to remove the memory that was allocated for an object 00181 */ 00182 //@{ 00183 /// Remove the memory for an object 00184 virtual int remove(void *vp) { return 0; } 00185 00186 /// Remove the memory for an array of objects 00187 virtual int remove_arr(void *vp) { 00188 return 0; 00189 } 00190 00191 /// Remove the memory for a 2-dimensional array of objects 00192 virtual int remove_2darr(void *vp, int sz) { return 0; } 00193 //@} 00194 00195 #endif 00196 00197 public: 00198 00199 /** 00200 \brief Create a new I/O object 00201 00202 If \c sw is different from zero, then the type will not 00203 be added to the io_manager. This is useful if you want 00204 an object to be its own I/O class, in which case you 00205 may want to make sure that the io_manager only tries 00206 to add the type once. There is no need to have an I/O 00207 object for every instance of a particular type. 00208 */ 00209 io_base(int sw=0); 00210 00211 /** \brief Create a new object only if an I/O object for type \c t 00212 is not yet present 00213 */ 00214 io_base(const char *t); 00215 00216 virtual ~io_base(); 00217 00218 /// \name Functions to be overloaded in descendants of io_base 00219 //@{ 00220 /// Return the type of an object 00221 virtual const char *type() { return "io_base"; } 00222 00223 /// If true, then the object contains static data 00224 virtual bool has_static_data() { return false; } 00225 //@} 00226 00227 /** \name Functions useful for in in() and out() 00228 */ 00229 //@{ 00230 /// Input a pointer 00231 virtual int pointer_in(cinput *co, in_file_format *ins, void **pp, 00232 std::string &stype); 00233 00234 /** 00235 \brief Output an object to \c outs of type \c stype 00236 00237 This is useful for to output a pointer to an object in the 00238 out() or stat_out() functions for a class. The data for 00239 the object which is pointed to is separate from the object 00240 and is only referred to once if more than one objects 00241 point to it. 00242 */ 00243 virtual int pointer_out(coutput *co, out_file_format *outs, void *ptr, 00244 std::string stype); 00245 //@} 00246 00247 }; 00248 00249 /** 00250 \brief Manage I/O type information 00251 00252 00253 00254 This class is automatically created, utilized, and destroyed by 00255 \ref io_base. 00256 */ 00257 class io_manager { 00258 00259 public: 00260 00261 /** 00262 \brief Add a type to the list 00263 00264 Unfortunately, add_type() cannot ensure that no type is added 00265 more than once, since the type is not specified until the 00266 entire constructor hierarchy has been executed and add_type() 00267 is called at the top of this hierarchy. 00268 */ 00269 int add_type(io_base *iop); 00270 00271 /// Return 0 if \c iop points to a valid type 00272 int is_type(io_base *iop); 00273 00274 /// Add type \c iop to the manager assuming the type name \c t 00275 int add_type(io_base *iop, const char *t); 00276 00277 /// Remove a type from the list 00278 int remove_type(io_base *iop); 00279 00280 #ifndef DOXYGEN_INTERNAL 00281 00282 protected: 00283 00284 /// So that io_base can access add_type(). 00285 friend class io_base; 00286 00287 /// So that collections can access get_ptr 00288 friend class collection; 00289 00290 /// So that cinputs can access get_ptr() 00291 friend class cinput; 00292 00293 /// So that coutputs can access get_ptr() 00294 friend class coutput; 00295 00296 // So that io_type_info can access tlist 00297 friend class io_type_info; 00298 00299 /// Get a pointer to type \c stype 00300 io_base *get_ptr(std::string stype); 00301 00302 /// The list of types in the form of io_base pointers 00303 std::vector<io_base *> tlist; 00304 00305 /// A useful definition for iterating through types 00306 typedef std::vector<io_base *>::iterator titer; 00307 00308 /// Empty constructor 00309 io_manager() {}; 00310 00311 #endif 00312 00313 }; 00314 00315 // ---------------------------------------------------------------- 00316 // Start of class io_type_info 00317 // ---------------------------------------------------------------- 00318 00319 /** 00320 \brief User interface to provide I/O type information 00321 00322 00323 */ 00324 class io_type_info : public io_base { 00325 00326 #ifndef DOXYGEN_INTERNAL 00327 00328 protected: 00329 00330 /// So that collection::fout() can access static_fout(). 00331 friend class collection; 00332 00333 /// Output the static information for the I/O types 00334 int static_fout(coutput *co, out_file_format *out); 00335 00336 /// Output the static information for the I/O types not in the list 00337 int static_fout_restricted(coutput *co, out_file_format *out, 00338 std::set<std::string,string_comp> list); 00339 00340 /// A useful definition for iterating through types 00341 typedef std::vector<io_base *>::iterator titer; 00342 00343 #endif 00344 00345 public: 00346 00347 io_type_info(); 00348 00349 virtual ~io_type_info(); 00350 00351 /** \name Type manipulation 00352 */ 00353 //@{ 00354 00355 /// Return 0 if \c stype is a valid I/O type 00356 int is_type(std::string stype); 00357 00358 /** 00359 \brief Remove \c stype from the list of valid I/O types 00360 00361 This method is dangerous, as it can't check to ensure that 00362 no collection has remaining objects of the type to be 00363 removed. 00364 */ 00365 int remove_type(std::string stype); 00366 00367 /** 00368 \brief Remove all types in the list of valid I/O types 00369 00370 This method is dangerous as it doesn't ensure that 00371 all collections are empty. 00372 */ 00373 virtual int clear_types(); 00374 00375 /// Print a summary of valid types to the \c outs stream 00376 void type_summary(std::ostream *outs, bool pointers=false); 00377 00378 /// Add an I/O type to the list 00379 int add_type(io_base *iop) { return iom->add_type(iop); } 00380 //@} 00381 00382 }; 00383 00384 // ---------------------------------------------------------------- 00385 // End of class io_type_info 00386 // ---------------------------------------------------------------- 00387 00388 // ---------------------------------------------------------------- 00389 // Start of class collection 00390 // ---------------------------------------------------------------- 00391 00392 /** 00393 \brief Collection of objects 00394 00395 00396 00397 By default, the fout() functions alphabetize the objects by name, 00398 but this is not a requirement for files read using fin(). 00399 00400 Important issues: 00401 1. Pointers are not set until after an entire file is read so that 00402 objects that are pointed to may occur anywhere in a file. This 00403 means that the information that is pointed to cannot be used in 00404 the io_tlate_d::input() function. 00405 00406 \todo 00407 - If pointer_in gets a null pointer it does nothing. Should we 00408 replace this behaviour by two pointer_in() functions. One which 00409 does nothing if it gets a null pointer, and one which will 00410 go ahead and set the pointer to null. This is useful for 00411 output object which have default values to be used if 00412 they are given a null pointer. 00413 - More testing on rewrite() function. 00414 - Think more about adding arrays of pointers? pointers to arrays? 00415 - Modify static data output so that if no objects of a type 00416 are included, then no static data is output for that type? 00417 (No, it's too hard to go through all objects looking for 00418 an object of a particular type). 00419 00420 \bug 00421 - Ensure that the user cannot add a object with a name of ptrXXX. 00422 - Test_type does not test handle static data or pointers. 00423 - Check strings and words for characters that we can't handle 00424 - The present version of a text-file requires 00425 strings to contain at least one printable character. 00426 - Ensure that all matching is done by both type and name if 00427 possible. 00428 00429 Structure: 00430 collection::fout() does the following: 00431 - create an object of type coutput 00432 - Add all objects in the list to the pointer map \c ptr_map 00433 (with \c output=true ) so that they can be referred to by 00434 pointers later 00435 - Output all static data using io_type_info::static_fout() 00436 - Output all of the items in the list \c plist (see 00437 below). Any pointers which are not already in \c ptr_map are 00438 added at this point (with \c output=false 00439 - Call coutput::pointer_map_fout() to output all objects that 00440 were referred to but not in the list 00441 00442 To output individual items, collection::fout() does the following: 00443 - Call either io_base::out_wrapper() or io_base::out_hc_wrapper() 00444 - In turn, these functions call io_base::output(), which the user 00445 has overloaded 00446 - If the function io_base::output() calls io_tlate::object_out() then the 00447 io_base::output() function appropriate for that object is called. 00448 No type or name information is included, but size integers are 00449 included if the object is a 1- or 2-d array. 00450 - If the function io_base::output() calls io_base::pointer_out(), then 00451 the object is searched for in the \c ptr_map . If it is 00452 not there, then the object is added and assigned a name. The 00453 type and name are then output. If the pointer is NULL, then 00454 both the type and the name are set to \c null . 00455 00456 */ 00457 class collection : public io_base { 00458 00459 #ifndef DOXYGEN_INTERNAL 00460 00461 protected: 00462 00463 friend class io_base; 00464 friend class cinput; 00465 friend class coutput; 00466 00467 /// A convenient iterator definition for the collection 00468 typedef std::map<std::string,collection_entry,string_comp>::iterator 00469 piter; 00470 00471 /// The actual collection 00472 std::map<std::string,collection_entry,string_comp> plist; 00473 00474 #endif 00475 00476 public: 00477 00478 collection() : io_base(1) { 00479 }; 00480 ~collection(); 00481 00482 /** \name Output to file methods */ 00483 //@{ 00484 00485 /// Output entire list to \c outs 00486 int fout(out_file_format *outs); 00487 00488 /// Output entire list to a textfile named \c filename 00489 int fout(std::string filename); 00490 //@} 00491 00492 /** \name Input from file methods 00493 If \c overwrt is true, then any objects which 00494 already exist with the same name are overwritten 00495 with the objects in the file. The collection 00496 owns all the objects read. (Since it created them, 00497 the collection assumes it ought to be responsible 00498 to destroy them.) 00499 */ 00500 //@{ 00501 /// Read a collection from text file named \c file_name 00502 int fin(std::string file_name, bool overwrt=false, int verbose=0); 00503 00504 /// Read a collection from \c ins 00505 int fin(in_file_format *ins, bool overwrt=false, int verbose=0); 00506 //@} 00507 00508 /** \name Miscellaneous methods 00509 */ 00510 //@{ 00511 00512 /// Test the output for type \c stype. 00513 int test_type(o2scl::test_mgr &t, std::string stype, void *obj, 00514 void *&newobj, bool scrout=false); 00515 00516 /** 00517 \brief Update a file containing a collection 00518 00519 This method loads the file from "fin" and produces a file at 00520 "fout" containing all of the objects from "fin", updated by 00521 their new values in the present list if possible. Then, it adds 00522 to the end of "fout" any objects in the present list that were 00523 not originally contained in "fin". 00524 */ 00525 int rewrite(std::string in_name, std::string out_name); 00526 00527 /** \brief Force the collection to assume that the ownership 00528 of \c name is external. 00529 00530 This allows the user to take over ownership of the object 00531 named \c name. This is particularly useful if the object is 00532 read from a file (since then object is owned initially by the 00533 collection), and you want to delete the collection, but retain 00534 the object. 00535 */ 00536 int disown(std::string name); 00537 00538 /** \brief Summarize contents of collection 00539 */ 00540 int summary(std::ostream *out, bool show_addresses=false); 00541 00542 /** 00543 \brief Remove an object for the collection 00544 00545 Free the memory \c name if it is owned by the collection 00546 and then remove it from the collection. 00547 */ 00548 int remove(std::string name); 00549 00550 /** \brief Remove all objects from the list 00551 */ 00552 void clear(); 00553 00554 /** 00555 \brief Count number of objects */ 00556 int npa(); 00557 00558 //@} 00559 00560 /** \name Generic add methods 00561 00562 If \c overwrt is true, then any objects which already exist 00563 with the same name as \c name are overwritten. If owner=true, 00564 then the collection will own the memory allocated for the 00565 object and will free that memory with delete when the object 00566 is removed or the collection is deleted. 00567 */ 00568 //@{ 00569 int add(std::string name, io_base *tio, void *vec, int sz=0, int sz2=0, 00570 bool overwrt=true, bool owner=false); 00571 00572 int add(std::string name, std::string stype, 00573 void *vec, int sz=0, int sz2=0, 00574 bool overwrt=true, bool owner=false); 00575 //@} 00576 00577 /** 00578 \name Generic get methods 00579 */ 00580 //@{ 00581 /** 00582 \brief Get an object 00583 */ 00584 int get(std::string tname, void *&vec); 00585 /** 00586 \brief Get an array of objects 00587 */ 00588 int get(std::string tname, void *&vec, int &sz); 00589 /** 00590 \brief Get a 2-d array of objects 00591 */ 00592 int get(std::string tname, void *&vec, int &sz, int &sz2); 00593 /** 00594 \brief Get an object and its type 00595 */ 00596 int get(std::string tname, std::string &stype, void *&vec); 00597 /** 00598 \brief Get an array of objects and their type 00599 */ 00600 int get(std::string tname, std::string &stype, void *&vec, int &sz); 00601 /** 00602 \brief Get a 2-d array of objects and their type 00603 */ 00604 int get(std::string tname, std::string &stype, void *&vec, int &sz, 00605 int &sz2); 00606 /** 00607 \brief Get an object (alternative form) 00608 */ 00609 void *get(std::string name) { 00610 void *vp; 00611 get(name,vp); 00612 return vp; 00613 } 00614 //@} 00615 00616 /// Output object of type \c stype and name \c name to output \c tof 00617 int get_type(text_out_file &tof, std::string stype, std::string name); 00618 00619 /// Output object with name \c name to output \c tof 00620 int get(text_out_file &tof, std::string &stype, std::string name); 00621 00622 /// Set object named \c name with input from \c tif 00623 int set(std::string name, text_in_file &tif); 00624 00625 /// Set object named \c name with input from \c val 00626 int set(std::string name, std::string val); 00627 00628 /** \name Input and output of individual objects */ 00629 //@{ 00630 /** 00631 \brief Output one object to a file 00632 00633 This does not disturb any objects in the collection. The 00634 pointer specified does not need to be in the collection and 00635 is not added to the collection. 00636 */ 00637 int out_one(out_file_format *outs, std::string stype, std::string name, 00638 void *vp, int sz=0, int sz2=0); 00639 00640 /** 00641 \brief Output one object to a file 00642 00643 This does not disturb any objects in the collection. The 00644 pointer specified does not need to be in the collection and 00645 is not added to the collection. 00646 */ 00647 int out_one(std::string fname, std::string stype, std::string name, 00648 void *vp, int sz=0, int sz2=0); 00649 00650 /** 00651 \brief Input one object from a file with name \c name 00652 00653 This does not disturb any objects in the collection. The 00654 pointer specified does not need to be in the collection and is 00655 not added to the collection. 00656 */ 00657 int in_one_name(in_file_format *ins, std::string stype, std::string name, 00658 void *&vp, int &sz, int &sz2); 00659 00660 /** 00661 \brief Input one object from a file 00662 00663 This does not disturb any objects in the collection. The 00664 pointer specified does not need to be in the collection and is 00665 not added to the collection. 00666 */ 00667 int in_one(in_file_format *ins, std::string stype, std::string &name, 00668 void *&vp, int &sz, int &sz2); 00669 00670 /** 00671 \brief Input one object from a file 00672 00673 This does not disturb any objects in the collection. The 00674 pointer specified does not need to be in the collection and is 00675 not added to the collection. 00676 */ 00677 int in_one(std::string fname, std::string stype, std::string &name, 00678 void *&vp, int &sz, int &sz2); 00679 //@} 00680 00681 /** 00682 \brief An iterator for stepping through a collection 00683 */ 00684 class iterator { 00685 00686 #ifndef DOXYGEN_INTERNAL 00687 00688 protected: 00689 00690 friend class collection; 00691 00692 /// Create an iterator from the STL iterator 00693 iterator(piter p) { pit=p; } 00694 00695 /// Local storage for the STL iterator 00696 piter pit; 00697 00698 #endif 00699 00700 public: 00701 00702 /// Prefix increment 00703 iterator operator++() { 00704 pit++; 00705 return *this; 00706 } 00707 00708 /// Postfix increment 00709 iterator operator++(int unused) { 00710 pit++; 00711 return *this; 00712 } 00713 00714 /// Prefix decrement 00715 iterator operator--() { 00716 pit--; 00717 return *this; 00718 } 00719 00720 /// Dereference 00721 collection_entry *operator->() const { 00722 return &(pit->second); 00723 }; 00724 00725 /// Return the name of the collection entry 00726 std::string name() { 00727 return pit->first; 00728 } 00729 00730 friend int operator==(const iterator &i1, const iterator &i2); 00731 00732 friend int operator!=(const iterator &i1, const iterator &i2); 00733 00734 }; 00735 00736 /** 00737 \brief An iterator for stepping through the entries 00738 in a collection of a particular type 00739 */ 00740 class type_iterator { 00741 00742 #ifndef DOXYGEN_INTERNAL 00743 00744 protected: 00745 00746 friend class collection; 00747 00748 /// Local storage for the type 00749 std::string ltype; 00750 00751 /// Store a pointer to the collection 00752 collection *lcop; 00753 00754 /// Constructor 00755 type_iterator(piter p, std::string type, collection *cop) { 00756 pit=p; 00757 ltype=type; 00758 lcop=cop; 00759 while (pit!=lcop->plist.end() && 00760 pit->second.iop->type()!=ltype) pit++; 00761 } 00762 00763 /// The STL iterator 00764 piter pit; 00765 00766 #endif 00767 00768 public: 00769 00770 /// Prefix increment 00771 type_iterator operator++() { 00772 if (pit!=lcop->plist.end()) pit++; 00773 while (pit!=lcop->plist.end() && 00774 pit->second.iop->type()!=ltype) pit++; 00775 return *this; 00776 } 00777 00778 /// Postfix increment 00779 type_iterator operator++(int unused) { 00780 if (pit!=lcop->plist.end()) pit++; 00781 while (pit!=lcop->plist.end() && 00782 pit->second.iop->type()!=ltype) pit++; 00783 return *this; 00784 } 00785 00786 /// Dereference 00787 collection_entry *operator->() const { 00788 return &(pit->second); 00789 }; 00790 00791 /// Return the name of the collection entry 00792 std::string name() { 00793 return pit->first; 00794 } 00795 00796 friend int operator==(const type_iterator &i1, const type_iterator &i2); 00797 00798 friend int operator!=(const type_iterator &i1, const type_iterator &i2); 00799 00800 }; 00801 00802 /** \name Iterator functions 00803 */ 00804 //@{ 00805 /// Return an iterator to the start of the collection 00806 iterator begin() { 00807 return iterator(plist.begin()); 00808 } 00809 00810 /// Return an iterator to the end of the collection 00811 iterator end() { 00812 return iterator(plist.end()); 00813 } 00814 00815 /** \brief Return an iterator to the first element of type \c utype 00816 in the collection 00817 */ 00818 type_iterator begin(std::string utype) { 00819 return type_iterator(plist.begin(),utype,this); 00820 } 00821 00822 /// Return an iterator to the end of the collection 00823 type_iterator end(std::string utype) { 00824 return type_iterator(plist.end(),utype,this); 00825 } 00826 //@} 00827 00828 }; 00829 // ---------------------------------------------------------------- 00830 // End of class collection 00831 // ---------------------------------------------------------------- 00832 00833 /// Equality comparison for two iterators 00834 int operator==(const collection::iterator &i1, 00835 const collection::iterator &i2); 00836 00837 /// Inequality comparison for two iterators 00838 int operator!=(const collection::iterator &i1, 00839 const collection::iterator &i2); 00840 00841 /// Equality comparison for two iterators 00842 int operator==(const collection::type_iterator &i1, 00843 const collection::type_iterator &i2); 00844 00845 /// Inequality comparison for two iterators 00846 int operator!=(const collection::type_iterator &i1, 00847 const collection::type_iterator &i2); 00848 00849 /** 00850 \brief Class to control object input 00851 00852 00853 */ 00854 class cinput { 00855 00856 public: 00857 00858 /// Input an object 00859 int object_in(std::string type, in_file_format *ins, void *vp, 00860 std::string &name); 00861 00862 /// Input an array of objects 00863 int object_in(std::string type, in_file_format *ins, void *vp, 00864 int sz, std::string &name); 00865 00866 /// Input a 2-d array of objects 00867 int object_in(std::string type, in_file_format *ins, void *vp, 00868 int sz, int sz2, std::string &name); 00869 00870 /// Input an object, allocating memory first 00871 int object_in_mem(std::string type, in_file_format *ins, void *&vp, 00872 std::string &name); 00873 00874 /// Input an array of objects, allocating memory first 00875 int object_in_mem(std::string type, in_file_format *ins, void *&vp, 00876 int &sz, std::string &name); 00877 00878 /// Input a 2-d array of objects, allocating memory first 00879 int object_in_mem(std::string type, in_file_format *ins, void *&vp, 00880 int &sz, int &sz2, std::string &name); 00881 00882 #ifndef DOXYGEN_INTERNAL 00883 00884 protected: 00885 00886 /// Create a new input object for a collection 00887 cinput(collection *co) { 00888 cop=co; 00889 } 00890 00891 friend class collection; 00892 friend class io_base; 00893 00894 /// The pointers that need to be set 00895 std::vector<pointer_input> input_ptrs; 00896 00897 /// An iterator for the input pointers 00898 typedef std::vector<pointer_input>::iterator ipiter; 00899 00900 /// Assign all of the pointers read with the appropriate objects 00901 int assign_pointers(collection *co); 00902 00903 /// The pointer to the collection stored in the constructor 00904 collection *cop; 00905 00906 #endif 00907 00908 }; 00909 00910 /** 00911 \brief Class to control object output 00912 00913 00914 */ 00915 class coutput { 00916 00917 public: 00918 00919 /// Output an object 00920 int object_out(std::string type, out_file_format *outs, 00921 void *op, int sz=0, int sz2=0, std::string name=""); 00922 00923 #ifndef DOXYGEN_INTERNAL 00924 00925 protected: 00926 00927 friend class collection; 00928 friend class io_base; 00929 00930 /// Create a new object from a pointer to a collection 00931 coutput(class collection *co) { 00932 cop=co; 00933 npointers=0; 00934 }; 00935 00936 /// Order the pointers by numeric value 00937 struct ltptr { 00938 /// Returns \f$ p_1 < p_2 \f$ 00939 bool operator()(const void * p1, const void * p2) const { 00940 return p1<p2; 00941 } 00942 }; 00943 00944 /// The list pointers to object to be written to the file 00945 std::map<void *,pointer_output,ltptr> ptr_map; 00946 00947 /// A convenient iterator for the pointer list 00948 typedef std::map<void *,pointer_output,ltptr>::iterator pmiter; 00949 00950 /** 00951 \brief Look for an object in the collection given a pointer 00952 00953 Lookup the pointer \c vp in the collection, and return 00954 its name and collection_entry 00955 */ 00956 int pointer_lookup(void *vp, std::string &name, collection_entry *&ep); 00957 00958 /// The pointer to the collection stored in the constructor 00959 collection *cop; 00960 00961 /// Output all of the remaining pointers to 'out' 00962 int pointer_map_fout(out_file_format *out); 00963 00964 /** 00965 \brief Keep track of the number of pointers added to ptr_map 00966 00967 These are counted for the purposes of making a unique name. 00968 This is initialized 00969 in fout() and incremented in io_base::pointer_out 00970 */ 00971 int npointers; 00972 00973 #endif 00974 00975 }; 00976 00977 /** 00978 00979 \brief A template for adding I/O classes 00980 00981 00982 */ 00983 template <class object> class io_vtlate : public io_base { 00984 00985 public: 00986 00987 /** \name Functions to be overloaded 00988 00989 These functions should be overloaded in all descendants of 00990 io_tlate. 00991 */ 00992 //@{ 00993 00994 /** \brief The name of the type to be processed */ 00995 virtual const char *type() { return "io_tlate"; } 00996 00997 /** \brief Method for reading an object from \c ins */ 00998 virtual int input(cinput *cin, in_file_format *ins, object *op) 00999 { return 0; } 01000 01001 /** 01002 \brief Method for writing an object to \c outs */ 01003 virtual int output(coutput *cout, out_file_format *outs, object *op) 01004 { return 0; } 01005 //@} 01006 01007 /** \name Functions to be overloaded for static data 01008 01009 These functions should be overloaded in all descendants of 01010 io_tlate which control I/O for classes which contain static 01011 data. 01012 */ 01013 //@{ 01014 01015 /** \brief \c true if the object contains static I/O data */ 01016 virtual bool has_static_data() { return false; } 01017 01018 /** \brief Method for reading static data for an object 01019 from \c ins 01020 01021 One must be careful about objects which set the static data in 01022 their constructors. An object is automatically created in order 01023 to read its static data. This means that if the static data is 01024 set in the constructor, then possibly useful information will be 01025 overwritten through the creation of this temporary object. 01026 01027 If one needs to set static data in the constructor of a 01028 singleton object, then the create() and remove() functions 01029 should be empty and a separate pointer to the singleton should 01030 be provided instead of void *vp. 01031 01032 This is only used if has_static_data() returns true; 01033 */ 01034 virtual int stat_input(cinput *cin, in_file_format *ins, object *op) 01035 { return 0; } 01036 01037 /** \brief Method for writing static data for an object 01038 to \c outs 01039 */ 01040 virtual int stat_output(coutput *cout, out_file_format *outs, 01041 object *op) 01042 { return 0; } 01043 //@} 01044 }; 01045 01046 /** \brief A template for adding I/O classes (documents template 01047 io_tlate) 01048 01049 01050 01051 Note that the generic interface here only works with 01052 pointers, not with the actual objects themselves. This 01053 is important, because it avoids the problem of I/O 01054 for an object with private copy and assigment operators. 01055 For basic types (bool, char, double, int, etc.), 01056 some additional add() and get() functions are defined. 01057 01058 */ 01059 template <class object> class io_tlate : public io_base { 01060 01061 public: 01062 01063 /// Create an I/O class for type \c object. 01064 io_tlate() : io_base() {}; 01065 01066 /** 01067 \brief Create an I/O class for type \c object only if another 01068 object of type \c t is not yet present 01069 */ 01070 io_tlate(const char *t) : io_base(t) {}; 01071 01072 /** \name Functions to be overloaded 01073 01074 These functions should be overloaded in all descendants of 01075 io_tlate. 01076 */ 01077 //@{ 01078 01079 /** \brief The name of the type to be processed */ 01080 virtual const char *type() { return "io_tlate"; } 01081 01082 /** \brief Method for reading an object from \c ins */ 01083 virtual int input(cinput *cin, in_file_format *ins, object *op) 01084 { return 0; } 01085 01086 /** 01087 \brief Method for writing an object to \c outs */ 01088 virtual int output(coutput *cout, out_file_format *outs, object *op) 01089 { return 0; } 01090 //@} 01091 01092 /** \name Functions to be overloaded for static data 01093 01094 These functions should be overloaded in all descendants of 01095 io_tlate which control I/O for classes which contain static 01096 data. 01097 */ 01098 //@{ 01099 01100 /** \brief \c true if the object contains static I/O data */ 01101 virtual bool has_static_data() { return false; } 01102 01103 /** \brief Method for reading static data for an object 01104 from \c ins 01105 01106 One must be careful about objects which set the static data in 01107 their constructors. An object is automatically created in order 01108 to read its static data. This means that if the static data is 01109 set in the constructor, then possibly useful information will be 01110 overwritten through the creation of this temporary object. 01111 01112 If one needs to set static data in the constructor of a 01113 singleton object, then the create() and remove() functions 01114 should be empty and a separate pointer to the singleton should 01115 be provided instead of void *vp. 01116 01117 This is only used if has_static_data() returns true; 01118 */ 01119 virtual int stat_input(cinput *cin, in_file_format *ins, object *op) 01120 { return 0; } 01121 01122 /** \brief Method for writing static data for an object 01123 to \c outs 01124 */ 01125 virtual int stat_output(coutput *cout, out_file_format *outs, 01126 object *op) 01127 { return 0; } 01128 //@} 01129 01130 #ifndef DOXYGEN_INTERNAL 01131 01132 protected: 01133 01134 virtual int object_in_void(cinput *cin, in_file_format *ins, void *op, 01135 std::string &name) { 01136 return object_in(cin,ins,(object *)op,name); 01137 } 01138 01139 virtual int object_in_void(cinput *cin, in_file_format *ins, void *op, 01140 int sz, std::string &name) { 01141 return object_in(cin,ins,(object *)op,sz,name); 01142 } 01143 01144 virtual int object_in_void(cinput *cin, in_file_format *ins, void *op, 01145 int sz, int sz2, std::string &name) { 01146 return object_in(cin,ins,(object **)op,sz,sz2,name); 01147 } 01148 01149 virtual int object_in_mem_void(cinput *cin, in_file_format *ins, 01150 void *&vp, std::string &name) { 01151 object *op; 01152 int ret=object_in_mem(cin,ins,op,name); 01153 vp=(void *)op; 01154 return ret; 01155 } 01156 01157 virtual int object_in_mem_void(cinput *cin, in_file_format *ins, void *&vp, 01158 int &sz,std::string &name) { 01159 object *op; 01160 int ret=object_in_mem(cin,ins,op,sz,name); 01161 vp=(void *)op; 01162 return ret; 01163 } 01164 01165 virtual int object_in_mem_void(cinput *cin, in_file_format *ins, void *&vp, 01166 int &sz, int &sz2, std::string &name) { 01167 object **op; 01168 int ret=object_in_mem(cin,ins,op,sz,sz2,name); 01169 vp=(void *)op; 01170 return ret; 01171 } 01172 01173 virtual int object_out_void(coutput *cout, out_file_format *outs, 01174 void *op, int sz=0, int sz2=0, 01175 std::string name="") { 01176 if (sz2==0) { 01177 return object_out(cout,outs,(object *)op,sz,name); 01178 } 01179 return object_out(cout,outs,(object **)op,sz,sz2,name); 01180 } 01181 01182 virtual int stat_in_noobj(cinput *cin, in_file_format *ins) { 01183 int ret; 01184 object *op=new object; 01185 ret=stat_input(cin,ins,op); 01186 return ret; 01187 }; 01188 01189 virtual int stat_out_noobj(coutput *cout, out_file_format *outs) { 01190 int ret; 01191 object *op=new object; 01192 ret=stat_output(cout,outs,op); 01193 return ret; 01194 }; 01195 01196 int in_wrapper(cinput *cin, in_file_format *ins, void *&vp) { 01197 object *op; 01198 if (vp==NULL) { 01199 op=new object; 01200 } else { 01201 op=(object *)vp; 01202 } 01203 input(cin,ins,op); 01204 if (vp==NULL) vp=(void *)op; 01205 return 0; 01206 } 01207 01208 int in_wrapper(cinput *cin, in_file_format *ins, void *&vp, int &sz) { 01209 object *op; 01210 ins->int_in(sz); 01211 if (vp==NULL) { 01212 op=new object[sz]; 01213 } else { 01214 op=(object *)vp; 01215 } 01216 for(int i=0;i<sz;i++) { 01217 input(cin,ins,&(op[i])); 01218 } 01219 if (vp==NULL) vp=(void *)op; 01220 return 0; 01221 } 01222 01223 int in_wrapper(cinput *cin, in_file_format *ins, void *&vp, int &sz, 01224 int &sz2) { 01225 object **op; 01226 ins->int_in(sz); 01227 ins->int_in(sz2); 01228 if (vp==NULL) { 01229 op=new object *[sz]; 01230 } else { 01231 op=(object **)vp; 01232 } 01233 for(int i=0;i<sz;i++) { 01234 if (vp==NULL) op[i]=new object[sz2]; 01235 for(int j=0;j<sz2;j++) { 01236 input(cin,ins,&(op[i][j])); 01237 } 01238 } 01239 if (vp==NULL) vp=(void *)op; 01240 return 0; 01241 } 01242 01243 int out_wrapper(coutput *cout, out_file_format *outs, void *vp, int sz, 01244 int sz2) { 01245 int i, j; 01246 std::string stype; 01247 object *op=(object *)vp; 01248 01249 if (sz==0 && sz2==0) { 01250 output(cout,outs,op); 01251 } else if (sz2==0) { 01252 outs->int_out(sz); 01253 for(i=0;i<sz;i++) { 01254 output(cout,outs,&(op[i])); 01255 } 01256 } else { 01257 object **aop=(object **)vp; 01258 outs->int_out(sz); 01259 outs->int_out(sz2); 01260 for(i=0;i<sz;i++) { 01261 for(j=0;j<sz2;j++) { 01262 output(cout,outs,&(aop[i][j])); 01263 } 01264 } 01265 } 01266 return 0; 01267 } 01268 01269 /// Remove the memory for an object 01270 virtual int remove(void *vp) { 01271 object *op=(object *)vp; 01272 delete op; 01273 return 0; 01274 } 01275 01276 /// Remove the memory for an array of objects 01277 virtual int remove_arr(void *vp) { 01278 object *op=(object *)vp; 01279 delete[] op; 01280 return 0; 01281 } 01282 01283 /// Remove the memory for a 2-dimensional array of objects 01284 virtual int remove_2darr(void *vp, int sz) { 01285 object **op=(object **)vp; 01286 for(int i=0;i<sz;i++) { 01287 delete[] op[i]; 01288 } 01289 delete[] op; 01290 return 0; 01291 } 01292 01293 /// Static input for an object 01294 virtual int stat_in_wrapper(cinput *cin, in_file_format *ins, void *vp) { 01295 object *op=(object *)vp; 01296 stat_input(cin,ins,op); 01297 return 0; 01298 } 01299 01300 /// Static output for an object 01301 virtual int stat_out_wrapper(coutput *cout, out_file_format *outs, 01302 void *vp) { 01303 object *op=(object *)vp; 01304 outs->start_object(type()); 01305 stat_output(cout,outs,op); 01306 outs->end_object(); 01307 return 0; 01308 } 01309 01310 #endif 01311 01312 public: 01313 01314 /** \name Input functions 01315 */ 01316 //@{ 01317 01318 /** \brief Read an object from \c ins */ 01319 virtual int object_in(cinput *cin, in_file_format *ins, object *op, 01320 std::string &name) { 01321 std::string typ; 01322 ins->start_object(typ,name); 01323 input(cin,ins,op); 01324 ins->end_object(); 01325 return 0; 01326 } 01327 01328 /** \brief Read an array of objects from \c ins */ 01329 virtual int object_in(cinput *cin, in_file_format *ins, object *op, 01330 int sz, std::string &name) { 01331 int i; 01332 01333 std::string typ; 01334 ins->start_object(typ,name); 01335 ins->int_in(sz); 01336 for(i=0;i<sz;i++) { 01337 input(cin,ins,&op[i]); 01338 } 01339 ins->end_object(); 01340 return 0; 01341 } 01342 01343 /** \brief Read a 2-d array of objects from \c ins */ 01344 virtual int object_in(cinput *cin, in_file_format *ins, object **op, 01345 int sz, int sz2, std::string &name) { 01346 int i, j; 01347 01348 std::string typ; 01349 ins->start_object(typ,name); 01350 ins->int_in(sz); 01351 ins->int_in(sz2); 01352 01353 for(i=0;i<sz;i++) { 01354 object *opx=op[i]; 01355 for(j=0;j<sz2;j++) { 01356 input(cin,ins,&opx[j]); 01357 } 01358 } 01359 ins->end_object(); 01360 return 0; 01361 } 01362 01363 /** \brief Create memory for a 2-d array of objects 01364 and read it from \c ins 01365 */ 01366 template<size_t N> 01367 int object_in(cinput *co, in_file_format *ins, 01368 object op[][N], int sz, std::string &name) { 01369 int i, j; 01370 01371 std::string typ; 01372 ins->start_object(typ,name); 01373 ins->int_in(sz); 01374 ins->int_in(((int)N)); 01375 01376 for(i=0;i<sz;i++) { 01377 for(j=0;j<N;j++) { 01378 input(co,ins,&op[i][j]); 01379 } 01380 } 01381 ins->end_object(); 01382 01383 return 0; 01384 } 01385 01386 /** \brief Create memory for an object and read it from \c ins */ 01387 virtual int object_in_mem(cinput *cin, in_file_format *ins, 01388 object *&op, std::string &name) { 01389 op=new object; 01390 std::string typ; 01391 ins->start_object(typ,name); 01392 input(cin,ins,op); 01393 ins->end_object(); 01394 return 0; 01395 } 01396 01397 /** \brief Create memory for an object and read it from \c ins */ 01398 virtual int object_in_mem(cinput *cin, in_file_format *ins, object *&op, 01399 int &sz, std::string &name) { 01400 int i; 01401 01402 std::string typ; 01403 ins->start_object(typ,name); 01404 ins->int_in(sz); 01405 op=new object[sz]; 01406 for(i=0;i<sz;i++) { 01407 input(cin,ins,&op[i]); 01408 } 01409 ins->end_object(); 01410 return 0; 01411 } 01412 01413 /** \brief Create memory for an object and read it from \c ins */ 01414 virtual int object_in_mem(cinput *cin, in_file_format *ins, 01415 object **&op, int &sz, int &sz2, 01416 std::string &name) { 01417 int i, j; 01418 01419 std::string typ; 01420 ins->start_object(typ,name); 01421 ins->int_in(sz); 01422 ins->int_in(sz2); 01423 01424 op=new object *[sz]; 01425 for(i=0;i<sz;i++) { 01426 op[i]=new object[sz2]; 01427 for(j=0;j<sz2;j++) { 01428 input(cin,ins,&op[i][j]); 01429 } 01430 } 01431 ins->end_object(); 01432 01433 return 0; 01434 } 01435 01436 /** \brief Create memory for a 2-d array of objects 01437 and read it from \c ins 01438 01439 Note that you must specify in advance the size \c N. 01440 */ 01441 template<size_t N> 01442 int object_in_mem(cinput *co, in_file_format *ins, 01443 object op[][N], int &sz, std::string &name) { 01444 int i, j; 01445 01446 std::string typ; 01447 ins->start_object(typ,name); 01448 ins->int_in(sz); 01449 ins->int_in(((int)N)); 01450 01451 // commented out on 3/10/05 - i don't think this should be here 01452 // op=new object *[sz]; 01453 for(i=0;i<sz;i++) { 01454 // commented out on 3/10/05 - i don't think this should be here 01455 // op[i]=new object[N]; 01456 for(j=0;j<N;j++) { 01457 input(co,ins,&op[i][j]); 01458 } 01459 } 01460 ins->end_object(); 01461 01462 return 0; 01463 } 01464 01465 //@} 01466 01467 /** \name Output functions 01468 */ 01469 //@{ 01470 /** \brief Output an object (or an array of objects) to \c outs 01471 */ 01472 virtual int object_out(coutput *cout, out_file_format *outs, object *op, 01473 int sz=0, std::string name="") { 01474 if (sz==0) { 01475 outs->start_object(type(),name); 01476 output(cout,outs,op); 01477 } else { 01478 outs->start_object(((std::string)(type()))+"[]",name); 01479 outs->int_out(sz); 01480 for(int i=0;i<sz;i++) { 01481 output(cout,outs,&op[i]); 01482 } 01483 } 01484 outs->end_object(); 01485 return 0; 01486 } 01487 01488 /** \brief Output an object (or an array of objects) to \c outs 01489 */ 01490 virtual int object_out(coutput *cout, out_file_format *outs, object **op, 01491 int sz, int sz2, std::string name="") { 01492 int i, j; 01493 01494 outs->start_object(((std::string)(type()))+"[][]",name); 01495 outs->int_out(sz); 01496 outs->int_out(sz2); 01497 for(i=0;i<sz;i++) { 01498 for(j=0;j<sz2;j++) { 01499 output(cout,outs,&(op[i][j])); 01500 } 01501 } 01502 outs->end_object(); 01503 return 0; 01504 } 01505 01506 /** \brief Output a 2-d array of objects to \c outs 01507 */ 01508 template<size_t N> 01509 int object_out(coutput *cout, out_file_format *outs, 01510 object op[][N], int sz, std::string name="") { 01511 int i, j; 01512 01513 outs->start_object(((std::string)(type()))+"[][]",name); 01514 outs->int_out(sz); 01515 outs->int_out(N); 01516 for(i=0;i<sz;i++) { 01517 for(j=0;j<N;j++) { 01518 output(cout,outs,&op[i][j]); 01519 } 01520 } 01521 outs->end_object(); 01522 return 0; 01523 } 01524 //@} 01525 01526 /** \name Memory allocation 01527 */ 01528 //@{ 01529 /** \brief Create memory for an object */ 01530 virtual int mem_alloc(object *&op) { 01531 op=new object; 01532 return 0; 01533 } 01534 01535 /** \brief Create memory for an object */ 01536 virtual int mem_alloc_arr(object *&op, int sz) { 01537 op=new object[sz]; 01538 return 0; 01539 } 01540 01541 /** \brief Create memory for an object */ 01542 virtual int mem_alloc_2darr(object **&op, int sz, int sz2) { 01543 op=new object *[sz]; 01544 for(int i=0;i<sz;i++) { 01545 op[i]=new object[sz2]; 01546 } 01547 return 0; 01548 } 01549 //@} 01550 01551 /** \name Add and get objects from a collection 01552 */ 01553 //@{ 01554 01555 /** \brief Add an object(s) to a collection */ 01556 int add(collection &coll, std::string name, object *op, int sz=0, 01557 bool overwrt=true, bool owner=false) { 01558 return coll.add(name,this,op,sz,0,overwrt,owner); 01559 } 01560 01561 /** \brief Add an object(s) to a collection */ 01562 int add_2darray(collection &coll, std::string name, object **op, int sz, 01563 int sz2, bool overwrt=true, bool owner=false) { 01564 return coll.add(name,this,op,sz,sz2,overwrt,owner); 01565 } 01566 01567 /** \brief Get an object(s) from a collection */ 01568 int get(collection &coll, std::string tname, object *&op) { 01569 void *vp; 01570 int ret=coll.get(tname,vp); 01571 if (ret==0) { 01572 op=(object *)vp; 01573 } else { 01574 op=NULL; 01575 return ret; 01576 } 01577 return 0; 01578 } 01579 01580 /** \brief Get an object(s) from a collection */ 01581 int get(collection &co, std::string tname, object *&op, int &sz) { 01582 void *vp; 01583 int ret=co.get(tname,vp,sz); 01584 if (ret==0) { 01585 op=(object *)vp; 01586 } else { 01587 op=NULL; 01588 return ret; 01589 } 01590 return 0; 01591 } 01592 01593 /** \brief Get an object(s) from a collection */ 01594 int get(collection &co, std::string tname, object **&op, int &sz, 01595 int &sz2) { 01596 void *vp; 01597 int ret=co.get(tname,vp,sz,sz2); 01598 if (ret==0) { 01599 op=(object **)vp; 01600 } else { 01601 op=NULL; 01602 return ret; 01603 } 01604 return 0; 01605 } 01606 //@} 01607 01608 /** \name Other functions 01609 */ 01610 //@{ 01611 01612 /// Free the memory associated with an object 01613 virtual int mem_free(object *op) { return remove((void *)op); } 01614 01615 /// Free the memory associated with an array of objects 01616 virtual int mem_free_arr(object *op) { return remove_arr((void *)op); } 01617 01618 /// Free the memory associated with a 2-d array of objects 01619 virtual int mem_free_2darr(object **op, int sz) 01620 { return remove_2darr((void *)op,sz); } 01621 01622 //@} 01623 01624 }; 01625 01626 01627 template<> int io_tlate<bool>::input 01628 (cinput *co, in_file_format *ins, bool *dp); 01629 template<> int io_tlate<bool>::output 01630 (coutput *co, out_file_format *outs, bool *dp); 01631 template<> const char *io_tlate<bool>::type(); 01632 01633 /** 01634 \brief I/O object for bool variables 01635 01636 01637 */ 01638 #ifdef DOXYGENP 01639 class bool_io_type : public io_tlate<object> 01640 #else 01641 class bool_io_type : public io_tlate<bool> 01642 #endif 01643 { 01644 public: 01645 01646 /// Desc 01647 bool_io_type(const char *t) : io_tlate<bool>(t) {}; 01648 01649 bool_io_type() : io_tlate<bool>() {}; 01650 01651 /// Add a bool to a collection 01652 int addb(collection &co, std::string name, bool x, bool overwrt=true); 01653 /// Get a bool from a collection 01654 bool getb(collection &co, std::string tname); 01655 /// Get a bool from a collection 01656 int get_def(collection &co, std::string tname, bool &op, bool def=false); 01657 }; 01658 01659 template<> int io_tlate<char>::input 01660 (cinput *co, in_file_format *ins, char *dp); 01661 template<> int io_tlate<char>::output 01662 (coutput *co, out_file_format *outs, char *dp); 01663 template<> const char *io_tlate<char>::type(); 01664 01665 /** 01666 \brief I/O object for char variables 01667 01668 01669 */ 01670 #ifdef DOXYGENP 01671 class char_io_type : public io_tlate<object> 01672 #else 01673 class char_io_type : public io_tlate<char> 01674 #endif 01675 { 01676 public: 01677 /// Desc 01678 char_io_type(const char *t) : io_tlate<char>(t) {}; 01679 01680 char_io_type() : io_tlate<char>() {}; 01681 01682 /// Add a char to a collection 01683 int addc(collection &co, std::string name, char x, bool overwrt=true); 01684 /** 01685 \brief Get a char from a collection 01686 01687 Some older systems have trouble with functions named \c getc, 01688 so this is named \c getcc instead. 01689 */ 01690 char getcc(collection &co, std::string tname); 01691 /// Get a char from a collection 01692 int get_def(collection &co, std::string tname, char &op, char def='x'); 01693 }; 01694 01695 template<> int io_tlate<double>::input 01696 (cinput *co, in_file_format *ins, double *dp); 01697 template<> int io_tlate<double>::output 01698 (coutput *co, out_file_format *outs, double *dp); 01699 template<> const char *io_tlate<double>::type(); 01700 01701 /** 01702 \brief I/O object for double variables 01703 01704 01705 */ 01706 #ifdef DOXYGENP 01707 class double_io_type : public io_tlate<object> 01708 #else 01709 class double_io_type : public io_tlate<double> 01710 #endif 01711 { 01712 public: 01713 /// Desc 01714 double_io_type(const char *t) : io_tlate<double>(t) {}; 01715 01716 double_io_type() : io_tlate<double>() {}; 01717 01718 /// Add a double to a collection 01719 int addd(collection &co, std::string name, double x, bool overwrt=true); 01720 /// Get a double from a collection 01721 double getd(collection &co, std::string tname); 01722 /// Get a double from a collection 01723 int get_def(collection &co, std::string tname, double &op, 01724 double def=0.0); 01725 }; 01726 01727 template<> int io_tlate<int>::input 01728 (cinput *co, in_file_format *ins, int *dp); 01729 template<> int io_tlate<int>::output 01730 (coutput *co, out_file_format *outs, int *dp); 01731 template<> const char *io_tlate<int>::type(); 01732 01733 /** 01734 \brief I/O object for int variables 01735 01736 01737 */ 01738 #ifdef DOXYGENP 01739 class int_io_type : public io_tlate<object> 01740 #else 01741 class int_io_type : public io_tlate<int> 01742 #endif 01743 { 01744 public: 01745 /// Desc 01746 int_io_type(const char *t) : io_tlate<int>(t) {}; 01747 01748 int_io_type() : io_tlate<int>() {}; 01749 01750 /// Add a int to a collection 01751 int addi(collection &co, std::string name, int x, bool overwrt=true); 01752 /// Get a int from a collection 01753 int geti(collection &co, std::string tname); 01754 /// Get a int from a collection 01755 int get_def(collection &co, std::string tname, int &op, 01756 int def=0); 01757 }; 01758 01759 template<> int io_tlate<unsigned long int>::input 01760 (cinput *co, in_file_format *ins, unsigned long int *dp); 01761 template<> int io_tlate<unsigned long int>::output 01762 (coutput *co, out_file_format *outs, unsigned long int *dp); 01763 template<> const char *io_tlate<unsigned long int>::type(); 01764 01765 /** 01766 \brief I/O object for long variables 01767 01768 01769 */ 01770 #ifdef DOXYGENP 01771 class long_io_type : public io_tlate<object> 01772 #else 01773 class long_io_type : public io_tlate<unsigned long int> 01774 #endif 01775 { 01776 public: 01777 /// Desc 01778 long_io_type(const char *t) : io_tlate<unsigned long int>(t) {}; 01779 01780 long_io_type() : io_tlate<unsigned long int>() {}; 01781 01782 /// Add a long to a collection 01783 int addl(collection &co, std::string name, unsigned long int x, 01784 bool overwrt=true); 01785 /// Get a long from a collection 01786 int getl(collection &co, std::string tname); 01787 /// Get a long from a collection 01788 int get_def(collection &co, std::string tname, unsigned long int &op, 01789 unsigned long int def=0); 01790 }; 01791 01792 template<> int io_tlate<std::string>::input 01793 (cinput *co, in_file_format *ins, std::string *dp); 01794 template<> int io_tlate<std::string>::output 01795 (coutput *co, out_file_format *outs, std::string *dp); 01796 template<> const char *io_tlate<std::string>::type(); 01797 01798 /** 01799 \brief I/O object for string variables 01800 01801 01802 */ 01803 #ifdef DOXYGENP 01804 class string_io_type : public io_tlate<object> 01805 #else 01806 class string_io_type : public io_tlate<std::string> 01807 #endif 01808 { 01809 public: 01810 /// Desc 01811 string_io_type(const char *t) : io_tlate<std::string>(t) {}; 01812 01813 string_io_type() : io_tlate<std::string>() {}; 01814 01815 /// Add a string to a collection 01816 int adds(collection &co, std::string name, std::string s, 01817 bool overwrt=true); 01818 /// Get a string from a collection 01819 std::string gets(collection &co, std::string tname); 01820 /// Get a string from a collection 01821 int get_def(collection &co, std::string tname, std::string &op, 01822 std::string def=""); 01823 }; 01824 01825 /** 01826 \brief I/O object for words 01827 01828 01829 */ 01830 #ifdef DOXYGENP 01831 class word_io_type : public io_tlate<object> 01832 #else 01833 class word_io_type : public io_tlate<std::string> 01834 #endif 01835 { 01836 public: 01837 /// Desc 01838 word_io_type(const char *t) : io_tlate<std::string>(t) {}; 01839 01840 word_io_type() : io_tlate<std::string>() {}; 01841 01842 /// Desc 01843 int input(cinput *co, in_file_format *ins, std::string *dp); 01844 /// Desc 01845 int output(coutput *co, out_file_format *outs, std::string *dp); 01846 /// Add a string to a collection 01847 int addw(collection &co, std::string name, std::string w, 01848 bool overwrt=true); 01849 /// Get a word from a collection 01850 std::string getw(collection &co, std::string tname); 01851 /// Get a word from a collection 01852 int get_def(collection &co, std::string tname, std::string &op, 01853 std::string def=""); 01854 /// Desc 01855 const char *type() { return "word"; } 01856 }; 01857 01858 #ifdef O2SCL_NEVER_DEFINED 01859 /** 01860 \brief I/O for ovector 01861 01862 01863 */ 01864 template<> int io_tlate<ovector>::input 01865 (cinput *co, in_file_format *ins, ovector *dp); 01866 template<> int io_tlate<ovector>::output 01867 (coutput *co, out_file_format *outs, ovector *dp); 01868 template<> const char *io_tlate<ovector>::type(); 01869 01870 /** 01871 \brief I/O for omatrix 01872 01873 01874 */ 01875 template<> int io_tlate<omatrix>::input 01876 (cinput *co, in_file_format *ins, omatrix *dp); 01877 template<> int io_tlate<omatrix>::output 01878 (coutput *co, out_file_format *outs, omatrix *dp); 01879 template<> const char *io_tlate<omatrix>::type(); 01880 01881 /** 01882 \brief I/O for ovector_int 01883 01884 01885 */ 01886 template<> int io_tlate<ovector_int>::input 01887 (cinput *co, in_file_format *ins, ovector_int *dp); 01888 template<> int io_tlate<ovector_int>::output 01889 (coutput *co, out_file_format *outs, ovector_int *dp); 01890 template<> const char *io_tlate<ovector_int>::type(); 01891 01892 /** 01893 \brief I/O for omatrix_int 01894 01895 01896 */ 01897 template<> int io_tlate<omatrix_int>::input 01898 (cinput *co, in_file_format *ins, omatrix_int *dp); 01899 template<> int io_tlate<omatrix_int>::output 01900 (coutput *co, out_file_format *outs, omatrix_int *dp); 01901 template<> const char *io_tlate<omatrix_int>::type(); 01902 01903 /** 01904 \brief I/O for ovector_cx 01905 01906 01907 */ 01908 template<> int io_tlate<ovector_cx>::input 01909 (cinput *co, in_file_format *ins, ovector_cx *dp); 01910 template<> int io_tlate<ovector_cx>::output 01911 (coutput *co, out_file_format *outs, ovector_cx *dp); 01912 template<> const char *io_tlate<ovector_cx>::type(); 01913 01914 /** 01915 \brief I/O for omatrix_cx 01916 01917 01918 */ 01919 template<> int io_tlate<omatrix_cx>::input 01920 (cinput *co, in_file_format *ins, omatrix_cx *dp); 01921 template<> int io_tlate<omatrix_cx>::output 01922 (coutput *co, out_file_format *outs, omatrix_cx *dp); 01923 template<> const char *io_tlate<omatrix_cx>::type(); 01924 01925 typedef io_tlate<ovector> ovector_io_type; 01926 typedef io_tlate<omatrix> omatrix_io_type; 01927 typedef io_tlate<ovector_int> ovector_int_io_type; 01928 typedef io_tlate<omatrix_int> omatrix_int_io_type; 01929 typedef io_tlate<ovector_cx> ovector_cx_io_type; 01930 typedef io_tlate<omatrix_cx> omatrix_cx_io_type; 01931 01932 #endif 01933 01934 #ifndef DOXYGENP 01935 } 01936 #endif 01937 01938 #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