00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 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 int i, j; 01322 01323 std::string typ; 01324 ins->start_object(typ,name); 01325 input(cin,ins,op); 01326 ins->end_object(); 01327 return 0; 01328 } 01329 01330 /** \brief Read an array of objects from \c ins */ 01331 virtual int object_in(cinput *cin, in_file_format *ins, object *op, 01332 int sz, std::string &name) { 01333 int i; 01334 01335 std::string typ; 01336 ins->start_object(typ,name); 01337 ins->int_in(sz); 01338 for(i=0;i<sz;i++) { 01339 input(cin,ins,&op[i]); 01340 } 01341 ins->end_object(); 01342 return 0; 01343 } 01344 01345 /** \brief Read a 2-d array of objects from \c ins */ 01346 virtual int object_in(cinput *cin, in_file_format *ins, object **op, 01347 int sz, int sz2, std::string &name) { 01348 int i, j; 01349 01350 std::string typ; 01351 ins->start_object(typ,name); 01352 ins->int_in(sz); 01353 ins->int_in(sz2); 01354 01355 for(i=0;i<sz;i++) { 01356 object *opx=op[i]; 01357 for(j=0;j<sz2;j++) { 01358 input(cin,ins,&opx[j]); 01359 } 01360 } 01361 ins->end_object(); 01362 return 0; 01363 } 01364 01365 /** \brief Create memory for a 2-d array of objects 01366 and read it from \c ins 01367 */ 01368 template<size_t N> 01369 int object_in(cinput *co, in_file_format *ins, 01370 object op[][N], int sz, std::string &name) { 01371 int i, j; 01372 01373 std::string typ; 01374 ins->start_object(typ,name); 01375 ins->int_in(sz); 01376 ins->int_in(((int)N)); 01377 01378 for(i=0;i<sz;i++) { 01379 for(j=0;j<N;j++) { 01380 input(co,ins,&op[i][j]); 01381 } 01382 } 01383 ins->end_object(); 01384 01385 return 0; 01386 } 01387 01388 /** \brief Create memory for an object and read it from \c ins */ 01389 virtual int object_in_mem(cinput *cin, in_file_format *ins, 01390 object *&op, std::string &name) { 01391 int i, j; 01392 op=new object; 01393 std::string typ; 01394 ins->start_object(typ,name); 01395 input(cin,ins,op); 01396 ins->end_object(); 01397 return 0; 01398 } 01399 01400 /** \brief Create memory for an object and read it from \c ins */ 01401 virtual int object_in_mem(cinput *cin, in_file_format *ins, object *&op, 01402 int &sz, std::string &name) { 01403 int i, j; 01404 01405 std::string typ; 01406 ins->start_object(typ,name); 01407 ins->int_in(sz); 01408 op=new object[sz]; 01409 for(i=0;i<sz;i++) { 01410 input(cin,ins,&op[i]); 01411 } 01412 ins->end_object(); 01413 return 0; 01414 } 01415 01416 /** \brief Create memory for an object and read it from \c ins */ 01417 virtual int object_in_mem(cinput *cin, in_file_format *ins, 01418 object **&op, int &sz, int &sz2, 01419 std::string &name) { 01420 int i, j; 01421 01422 std::string typ; 01423 ins->start_object(typ,name); 01424 ins->int_in(sz); 01425 ins->int_in(sz2); 01426 01427 op=new object *[sz]; 01428 for(i=0;i<sz;i++) { 01429 op[i]=new object[sz2]; 01430 for(j=0;j<sz2;j++) { 01431 input(cin,ins,&op[i][j]); 01432 } 01433 } 01434 ins->end_object(); 01435 01436 return 0; 01437 } 01438 01439 /** \brief Create memory for a 2-d array of objects 01440 and read it from \c ins 01441 01442 Note that you must specify in advance the size \c N. 01443 */ 01444 template<size_t N> 01445 int object_in_mem(cinput *co, in_file_format *ins, 01446 object op[][N], int &sz, std::string &name) { 01447 int i, j; 01448 01449 std::string typ; 01450 ins->start_object(typ,name); 01451 ins->int_in(sz); 01452 ins->int_in(((int)N)); 01453 01454 // commented out on 3/10/05 - i don't think this should be here 01455 // op=new object *[sz]; 01456 for(i=0;i<sz;i++) { 01457 // commented out on 3/10/05 - i don't think this should be here 01458 // op[i]=new object[N]; 01459 for(j=0;j<N;j++) { 01460 input(co,ins,&op[i][j]); 01461 } 01462 } 01463 ins->end_object(); 01464 01465 return 0; 01466 } 01467 01468 //@} 01469 01470 /** \name Output functions 01471 */ 01472 //@{ 01473 /** \brief Output an object (or an array of objects) to \c outs 01474 */ 01475 virtual int object_out(coutput *cout, out_file_format *outs, object *op, 01476 int sz=0, std::string name="") { 01477 if (sz==0) { 01478 outs->start_object(type(),name); 01479 output(cout,outs,op); 01480 } else { 01481 outs->start_object(((std::string)(type()))+"[]",name); 01482 outs->int_out(sz); 01483 for(int i=0;i<sz;i++) { 01484 output(cout,outs,&op[i]); 01485 } 01486 } 01487 outs->end_object(); 01488 return 0; 01489 } 01490 01491 /** \brief Output an object (or an array of objects) to \c outs 01492 */ 01493 virtual int object_out(coutput *cout, out_file_format *outs, object **op, 01494 int sz, int sz2, std::string name="") { 01495 int i, j; 01496 01497 outs->start_object(((std::string)(type()))+"[][]",name); 01498 outs->int_out(sz); 01499 outs->int_out(sz2); 01500 for(i=0;i<sz;i++) { 01501 for(j=0;j<sz2;j++) { 01502 output(cout,outs,&(op[i][j])); 01503 } 01504 } 01505 outs->end_object(); 01506 return 0; 01507 } 01508 01509 /** \brief Output a 2-d array of objects to \c outs 01510 */ 01511 template<size_t N> 01512 int object_out(coutput *cout, out_file_format *outs, 01513 object op[][N], int sz, std::string name="") { 01514 int i, j; 01515 01516 outs->start_object(((std::string)(type()))+"[][]",name); 01517 outs->int_out(sz); 01518 outs->int_out(N); 01519 for(i=0;i<sz;i++) { 01520 for(j=0;j<N;j++) { 01521 output(cout,outs,&op[i][j]); 01522 } 01523 } 01524 outs->end_object(); 01525 return 0; 01526 } 01527 //@} 01528 01529 /** \name Memory allocation 01530 */ 01531 //@{ 01532 /** \brief Create memory for an object */ 01533 virtual int mem_alloc(object *&op) { 01534 op=new object; 01535 return 0; 01536 } 01537 01538 /** \brief Create memory for an object */ 01539 virtual int mem_alloc_arr(object *&op, int sz) { 01540 op=new object[sz]; 01541 return 0; 01542 } 01543 01544 /** \brief Create memory for an object */ 01545 virtual int mem_alloc_2darr(object **&op, int sz, int sz2) { 01546 op=new object *[sz]; 01547 for(int i=0;i<sz;i++) { 01548 op[i]=new object[sz2]; 01549 } 01550 return 0; 01551 } 01552 //@} 01553 01554 /** \name Add and get objects from a collection 01555 */ 01556 //@{ 01557 01558 /** \brief Add an object(s) to a collection */ 01559 int add(collection &coll, std::string name, object *op, int sz=0, 01560 bool overwrt=true, bool owner=false) { 01561 return coll.add(name,this,op,sz,0,overwrt,owner); 01562 } 01563 01564 /** \brief Add an object(s) to a collection */ 01565 int add_2darray(collection &coll, std::string name, object **op, int sz, 01566 int sz2, bool overwrt=true, bool owner=false) { 01567 return coll.add(name,this,op,sz,sz2,overwrt,owner); 01568 } 01569 01570 /** \brief Get an object(s) from a collection */ 01571 int get(collection &coll, std::string tname, object *&op) { 01572 void *vp; 01573 int ret=coll.get(tname,vp); 01574 if (ret==0) { 01575 op=(object *)vp; 01576 } else { 01577 op=NULL; 01578 return ret; 01579 } 01580 return 0; 01581 } 01582 01583 /** \brief Get an object(s) from a collection */ 01584 int get(collection &co, std::string tname, object *&op, int &sz) { 01585 void *vp; 01586 int ret=co.get(tname,vp,sz); 01587 if (ret==0) { 01588 op=(object *)vp; 01589 } else { 01590 op=NULL; 01591 return ret; 01592 } 01593 return 0; 01594 } 01595 01596 /** \brief Get an object(s) from a collection */ 01597 int get(collection &co, std::string tname, object **&op, int &sz, 01598 int &sz2) { 01599 void *vp; 01600 int ret=co.get(tname,vp,sz,sz2); 01601 if (ret==0) { 01602 op=(object **)vp; 01603 } else { 01604 op=NULL; 01605 return ret; 01606 } 01607 return 0; 01608 } 01609 //@} 01610 01611 /** \name Other functions 01612 */ 01613 //@{ 01614 01615 /// Free the memory associated with an object 01616 virtual int mem_free(object *op) { return remove((void *)op); } 01617 01618 /// Free the memory associated with an array of objects 01619 virtual int mem_free_arr(object *op) { return remove_arr((void *)op); } 01620 01621 /// Free the memory associated with a 2-d array of objects 01622 virtual int mem_free_2darr(object **op, int sz) 01623 { return remove_2darr((void *)op,sz); } 01624 01625 //@} 01626 01627 }; 01628 01629 01630 template<> int io_tlate<bool>::input 01631 (cinput *co, in_file_format *ins, bool *dp); 01632 template<> int io_tlate<bool>::output 01633 (coutput *co, out_file_format *outs, bool *dp); 01634 template<> const char *io_tlate<bool>::type(); 01635 01636 /** 01637 \brief I/O object for bool variables 01638 01639 01640 */ 01641 #ifdef DOXYGENP 01642 class bool_io_type : public io_tlate<object> 01643 #else 01644 class bool_io_type : public io_tlate<bool> 01645 #endif 01646 { 01647 public: 01648 01649 /// Desc 01650 bool_io_type(const char *t) : io_tlate<bool>(t) {}; 01651 01652 bool_io_type() : io_tlate<bool>() {}; 01653 01654 /// Add a bool to a collection 01655 int addb(collection &co, std::string name, bool x, bool overwrt=true); 01656 /// Get a bool from a collection 01657 bool getb(collection &co, std::string tname); 01658 /// Get a bool from a collection 01659 int get_def(collection &co, std::string tname, bool &op, bool def=false); 01660 }; 01661 01662 template<> int io_tlate<char>::input 01663 (cinput *co, in_file_format *ins, char *dp); 01664 template<> int io_tlate<char>::output 01665 (coutput *co, out_file_format *outs, char *dp); 01666 template<> const char *io_tlate<char>::type(); 01667 01668 /** 01669 \brief I/O object for char variables 01670 01671 01672 */ 01673 #ifdef DOXYGENP 01674 class char_io_type : public io_tlate<object> 01675 #else 01676 class char_io_type : public io_tlate<char> 01677 #endif 01678 { 01679 public: 01680 /// Desc 01681 char_io_type(const char *t) : io_tlate<char>(t) {}; 01682 01683 char_io_type() : io_tlate<char>() {}; 01684 01685 /// Add a char to a collection 01686 int addc(collection &co, std::string name, char x, bool overwrt=true); 01687 /** 01688 \brief Get a char from a collection 01689 01690 Some older systems have trouble with functions named \c getc, 01691 so this is named \c getcc instead. 01692 */ 01693 char getcc(collection &co, std::string tname); 01694 /// Get a char from a collection 01695 int get_def(collection &co, std::string tname, char &op, char def='x'); 01696 }; 01697 01698 template<> int io_tlate<double>::input 01699 (cinput *co, in_file_format *ins, double *dp); 01700 template<> int io_tlate<double>::output 01701 (coutput *co, out_file_format *outs, double *dp); 01702 template<> const char *io_tlate<double>::type(); 01703 01704 /** 01705 \brief I/O object for double variables 01706 01707 01708 */ 01709 #ifdef DOXYGENP 01710 class double_io_type : public io_tlate<object> 01711 #else 01712 class double_io_type : public io_tlate<double> 01713 #endif 01714 { 01715 public: 01716 /// Desc 01717 double_io_type(const char *t) : io_tlate<double>(t) {}; 01718 01719 double_io_type() : io_tlate<double>() {}; 01720 01721 /// Add a double to a collection 01722 int addd(collection &co, std::string name, double x, bool overwrt=true); 01723 /// Get a double from a collection 01724 double getd(collection &co, std::string tname); 01725 /// Get a double from a collection 01726 int get_def(collection &co, std::string tname, double &op, 01727 double def=0.0); 01728 }; 01729 01730 template<> int io_tlate<int>::input 01731 (cinput *co, in_file_format *ins, int *dp); 01732 template<> int io_tlate<int>::output 01733 (coutput *co, out_file_format *outs, int *dp); 01734 template<> const char *io_tlate<int>::type(); 01735 01736 /** 01737 \brief I/O object for int variables 01738 01739 01740 */ 01741 #ifdef DOXYGENP 01742 class int_io_type : public io_tlate<object> 01743 #else 01744 class int_io_type : public io_tlate<int> 01745 #endif 01746 { 01747 public: 01748 /// Desc 01749 int_io_type(const char *t) : io_tlate<int>(t) {}; 01750 01751 int_io_type() : io_tlate<int>() {}; 01752 01753 /// Add a int to a collection 01754 int addi(collection &co, std::string name, int x, bool overwrt=true); 01755 /// Get a int from a collection 01756 int geti(collection &co, std::string tname); 01757 /// Get a int from a collection 01758 int get_def(collection &co, std::string tname, int &op, 01759 int def=0); 01760 }; 01761 01762 template<> int io_tlate<unsigned long int>::input 01763 (cinput *co, in_file_format *ins, unsigned long int *dp); 01764 template<> int io_tlate<unsigned long int>::output 01765 (coutput *co, out_file_format *outs, unsigned long int *dp); 01766 template<> const char *io_tlate<unsigned long int>::type(); 01767 01768 /** 01769 \brief I/O object for long variables 01770 01771 01772 */ 01773 #ifdef DOXYGENP 01774 class long_io_type : public io_tlate<object> 01775 #else 01776 class long_io_type : public io_tlate<unsigned long int> 01777 #endif 01778 { 01779 public: 01780 /// Desc 01781 long_io_type(const char *t) : io_tlate<unsigned long int>(t) {}; 01782 01783 long_io_type() : io_tlate<unsigned long int>() {}; 01784 01785 /// Add a long to a collection 01786 int addl(collection &co, std::string name, unsigned long int x, 01787 bool overwrt=true); 01788 /// Get a long from a collection 01789 int getl(collection &co, std::string tname); 01790 /// Get a long from a collection 01791 int get_def(collection &co, std::string tname, unsigned long int &op, 01792 unsigned long int def=0); 01793 }; 01794 01795 template<> int io_tlate<std::string>::input 01796 (cinput *co, in_file_format *ins, std::string *dp); 01797 template<> int io_tlate<std::string>::output 01798 (coutput *co, out_file_format *outs, std::string *dp); 01799 template<> const char *io_tlate<std::string>::type(); 01800 01801 /** 01802 \brief I/O object for string variables 01803 01804 01805 */ 01806 #ifdef DOXYGENP 01807 class string_io_type : public io_tlate<object> 01808 #else 01809 class string_io_type : public io_tlate<std::string> 01810 #endif 01811 { 01812 public: 01813 /// Desc 01814 string_io_type(const char *t) : io_tlate<std::string>(t) {}; 01815 01816 string_io_type() : io_tlate<std::string>() {}; 01817 01818 /// Add a string to a collection 01819 int adds(collection &co, std::string name, std::string s, 01820 bool overwrt=true); 01821 /// Get a string from a collection 01822 std::string gets(collection &co, std::string tname); 01823 /// Get a string from a collection 01824 int get_def(collection &co, std::string tname, std::string &op, 01825 std::string def=""); 01826 }; 01827 01828 /** 01829 \brief I/O object for words 01830 01831 01832 */ 01833 #ifdef DOXYGENP 01834 class word_io_type : public io_tlate<object> 01835 #else 01836 class word_io_type : public io_tlate<std::string> 01837 #endif 01838 { 01839 public: 01840 /// Desc 01841 word_io_type(const char *t) : io_tlate<std::string>(t) {}; 01842 01843 word_io_type() : io_tlate<std::string>() {}; 01844 01845 /// Desc 01846 int input(cinput *co, in_file_format *ins, std::string *dp); 01847 /// Desc 01848 int output(coutput *co, out_file_format *outs, std::string *dp); 01849 /// Add a string to a collection 01850 int addw(collection &co, std::string name, std::string w, 01851 bool overwrt=true); 01852 /// Get a word from a collection 01853 std::string getw(collection &co, std::string tname); 01854 /// Get a word from a collection 01855 int get_def(collection &co, std::string tname, std::string &op, 01856 std::string def=""); 01857 /// Desc 01858 const char *type() { return "word"; } 01859 }; 01860 01861 #ifdef NEVER_DEFINED 01862 /** 01863 \brief I/O for ovector 01864 01865 01866 */ 01867 template<> int io_tlate<ovector>::input 01868 (cinput *co, in_file_format *ins, ovector *dp); 01869 template<> int io_tlate<ovector>::output 01870 (coutput *co, out_file_format *outs, ovector *dp); 01871 template<> const char *io_tlate<ovector>::type(); 01872 01873 /** 01874 \brief I/O for omatrix 01875 01876 01877 */ 01878 template<> int io_tlate<omatrix>::input 01879 (cinput *co, in_file_format *ins, omatrix *dp); 01880 template<> int io_tlate<omatrix>::output 01881 (coutput *co, out_file_format *outs, omatrix *dp); 01882 template<> const char *io_tlate<omatrix>::type(); 01883 01884 /** 01885 \brief I/O for ovector_int 01886 01887 01888 */ 01889 template<> int io_tlate<ovector_int>::input 01890 (cinput *co, in_file_format *ins, ovector_int *dp); 01891 template<> int io_tlate<ovector_int>::output 01892 (coutput *co, out_file_format *outs, ovector_int *dp); 01893 template<> const char *io_tlate<ovector_int>::type(); 01894 01895 /** 01896 \brief I/O for omatrix_int 01897 01898 01899 */ 01900 template<> int io_tlate<omatrix_int>::input 01901 (cinput *co, in_file_format *ins, omatrix_int *dp); 01902 template<> int io_tlate<omatrix_int>::output 01903 (coutput *co, out_file_format *outs, omatrix_int *dp); 01904 template<> const char *io_tlate<omatrix_int>::type(); 01905 01906 /** 01907 \brief I/O for ovector_cx 01908 01909 01910 */ 01911 template<> int io_tlate<ovector_cx>::input 01912 (cinput *co, in_file_format *ins, ovector_cx *dp); 01913 template<> int io_tlate<ovector_cx>::output 01914 (coutput *co, out_file_format *outs, ovector_cx *dp); 01915 template<> const char *io_tlate<ovector_cx>::type(); 01916 01917 /** 01918 \brief I/O for omatrix_cx 01919 01920 01921 */ 01922 template<> int io_tlate<omatrix_cx>::input 01923 (cinput *co, in_file_format *ins, omatrix_cx *dp); 01924 template<> int io_tlate<omatrix_cx>::output 01925 (coutput *co, out_file_format *outs, omatrix_cx *dp); 01926 template<> const char *io_tlate<omatrix_cx>::type(); 01927 01928 typedef io_tlate<ovector> ovector_io_type; 01929 typedef io_tlate<omatrix> omatrix_io_type; 01930 typedef io_tlate<ovector_int> ovector_int_io_type; 01931 typedef io_tlate<omatrix_int> omatrix_int_io_type; 01932 typedef io_tlate<ovector_cx> ovector_cx_io_type; 01933 typedef io_tlate<omatrix_cx> omatrix_cx_io_type; 01934 01935 #endif 01936 01937 #ifndef DOXYGENP 01938 } 01939 #endif 01940 01941 #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