parameters.h
Go to the documentation of this file.00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2012 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 00003 00004 // This library is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public 00006 // License as published by the Free Software Foundation; either 00007 // version 2.1 of the License, or (at your option) any later version. 00008 00009 // This library is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // Lesser General Public License for more details. 00013 00014 // You should have received a copy of the GNU Lesser General Public 00015 // License along with this library; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 00019 00020 #ifndef LIBMESH_PARAMETERS_H 00021 #define LIBMESH_PARAMETERS_H 00022 00023 // C++ includes 00024 #include <typeinfo> 00025 #include <string> 00026 #include <map> 00027 00028 // Local includes 00029 #include "libmesh/libmesh_common.h" 00030 #include "libmesh/reference_counted_object.h" 00031 #include "libmesh/print_trace.h" 00032 00033 // C++ includes 00034 #include <cstddef> 00035 #include <map> 00036 #include <string> 00037 #include <typeinfo> 00038 00039 namespace libMesh 00040 { 00044 template<typename P> 00045 void print_helper(std::ostream& os, const P* param); 00046 00047 template<typename P> 00048 void print_helper(std::ostream& os, const std::vector<P>* param); 00049 00060 // ------------------------------------------------------------ 00061 // Parameters class definition 00062 class Parameters 00063 { 00064 public: 00065 00069 Parameters () {} 00070 00074 Parameters (const Parameters&); 00075 00079 virtual ~Parameters (); 00080 00085 virtual Parameters& operator= (const Parameters& source); 00086 00092 virtual Parameters& operator+= (const Parameters& source); 00093 00101 template <typename T> 00102 bool have_parameter (const std::string&) const; 00103 00108 template <typename T> 00109 const T& get (const std::string&) const; 00110 00116 template <typename T> 00117 void insert (const std::string&); 00118 00125 template <typename T> 00126 T& set (const std::string&); 00127 00132 virtual void set_attributes(const std::string&, bool /*inserted_only*/) {} 00133 00137 void remove (const std::string&); 00138 00142 std::size_t n_parameters () const { return _values.size(); } 00143 00144 #ifdef LIBMESH_HAVE_RTTI 00145 00148 template <typename T> 00149 unsigned int n_parameters () const; 00150 #endif // LIBMESH_HAVE_RTTI 00151 00155 virtual void clear (); 00156 00160 void print (std::ostream& os=libMesh::out) const; 00161 00162 private: 00163 00167 class Value : public ReferenceCountedObject<Value> 00168 { 00169 public: 00170 00174 virtual ~Value() {} 00175 00176 #ifdef LIBMESH_HAVE_RTTI 00177 00181 virtual std::string type () const = 0; 00182 #endif // LIBMESH_HAVE_RTTI 00183 00188 virtual void print(std::ostream&) const = 0; 00189 00194 virtual Value* clone () const = 0; 00195 }; 00196 00197 public: 00198 00203 template <typename T> 00204 class Parameter : public Value 00205 { 00206 public: 00207 00211 const T& get () const { return _value; } 00212 00216 T& set () { return _value; } 00217 00218 #ifdef LIBMESH_HAVE_RTTI 00219 00222 virtual std::string type () const; 00223 #endif // LIBMESH_HAVE_RTTI 00224 00228 virtual void print(std::ostream&) const; 00229 00233 virtual Value* clone () const; 00234 00235 private: 00239 T _value; 00240 }; 00241 00245 typedef std::map<std::string, Value*>::iterator iterator; 00246 00250 typedef std::map<std::string, Value*>::const_iterator const_iterator; 00251 00255 iterator begin(); 00256 00260 const_iterator begin() const; 00261 00265 iterator end(); 00266 00270 const_iterator end() const; 00271 00272 protected: 00273 00277 std::map<std::string, Value*> _values; 00278 00279 }; 00280 00281 // ------------------------------------------------------------ 00282 // Parameters::Parameter<> class inline methods 00283 00284 // This only works with Run-Time Type Information, even though 00285 // typeid(T) *should* be determinable at compile time regardless... 00286 #ifdef LIBMESH_HAVE_RTTI 00287 template <typename T> 00288 inline 00289 std::string Parameters::Parameter<T>::type () const 00290 { 00291 return demangle(typeid(T).name()); 00292 } 00293 #endif 00294 00295 template <typename T> 00296 inline 00297 void Parameters::Parameter<T>::print (std::ostream& os) const 00298 { 00299 // Call helper function overloaded for basic scalar and vector types 00300 print_helper(os, static_cast<const T*>(&_value)); 00301 } 00302 00303 template <typename T> 00304 inline 00305 Parameters::Value* Parameters::Parameter<T>::clone () const 00306 { 00307 // No good for Solaris C++! - BSK 00308 // Parameters::Parameter<T> 00309 // *copy = new Parameters::Parameter<T>; 00310 Parameter<T> 00311 *copy = new Parameter<T>; 00312 00313 libmesh_assert(copy); 00314 00315 copy->_value = _value; 00316 00317 return copy; 00318 } 00319 00320 00321 // ------------------------------------------------------------ 00322 // Parameters class inline methods 00323 inline 00324 void Parameters::clear () // since this is inline we must define it 00325 { // before its first use (for some compilers) 00326 while (!_values.empty()) 00327 { 00328 Parameters::iterator it = _values.begin(); 00329 00330 delete it->second; 00331 it->second = NULL; 00332 00333 _values.erase(it); 00334 } 00335 } 00336 00337 00338 00339 inline 00340 Parameters& Parameters::operator= (const Parameters& source) 00341 { 00342 this->clear(); 00343 00344 return (*this += source); 00345 } 00346 00347 inline 00348 Parameters& Parameters::operator+= (const Parameters& source) 00349 { 00350 for (Parameters::const_iterator it = source._values.begin(); 00351 it != source._values.end(); ++it) 00352 { 00353 if (_values.find(it->first) != _values.end()) 00354 delete _values[it->first]; 00355 _values[it->first] = it->second->clone(); 00356 } 00357 00358 return *this; 00359 } 00360 00361 inline 00362 Parameters::Parameters (const Parameters& p) 00363 { 00364 *this = p; 00365 } 00366 00367 00368 00369 inline 00370 Parameters::~Parameters () 00371 { 00372 this->clear (); 00373 } 00374 00375 00376 00377 inline 00378 void Parameters::print (std::ostream& os) const 00379 { 00380 Parameters::const_iterator it = _values.begin(); 00381 00382 os << "Name\t Type\t Value\n" 00383 << "---------------------\n"; 00384 while (it != _values.end()) 00385 { 00386 os << " " << it->first 00387 #ifdef LIBMESH_HAVE_RTTI 00388 << "\t " << it->second->type() 00389 #endif // LIBMESH_HAVE_RTTI 00390 << "\t "; it->second->print(os); 00391 os << '\n'; 00392 00393 ++it; 00394 } 00395 } 00396 00397 00398 00399 // Declare this now that Paramers::print() is defined. 00400 // By declaring this early we can use it in subsequent 00401 // methods. Required for gcc-4.0.2 -- 11/30/2005, BSK 00402 inline 00403 std::ostream& operator << (std::ostream& os, const Parameters& p) 00404 { 00405 p.print(os); 00406 return os; 00407 } 00408 00409 00410 00411 template <typename T> 00412 inline 00413 bool Parameters::have_parameter (const std::string& name) const 00414 { 00415 Parameters::const_iterator it = _values.find(name); 00416 00417 if (it != _values.end()) 00418 #ifdef LIBMESH_HAVE_RTTI 00419 if (dynamic_cast<const Parameter<T>*>(it->second) != NULL) 00420 #else // LIBMESH_HAVE_RTTI 00421 if (libmesh_cast_ptr<const Parameter<T>*>(it->second) != NULL) 00422 #endif // LIBMESH_HAVE_RTTI 00423 return true; 00424 00425 return false; 00426 } 00427 00428 00429 00430 template <typename T> 00431 inline 00432 const T& Parameters::get (const std::string& name) const 00433 { 00434 if (!this->have_parameter<T>(name)) 00435 { 00436 libMesh::err << "ERROR: no" 00437 #ifdef LIBMESH_HAVE_RTTI 00438 << ' ' << demangle(typeid(T).name()) 00439 #endif // LIBMESH_HAVE_RTTI 00440 << " parameter named \"" 00441 << name << "\":" << std::endl 00442 << *this; 00443 00444 libmesh_error(); 00445 } 00446 00447 Parameters::const_iterator it = _values.find(name); 00448 00449 libmesh_assert(it != _values.end()); 00450 libmesh_assert(it->second); 00451 00452 return libmesh_cast_ptr<Parameter<T>*>(it->second)->get(); 00453 } 00454 00455 template <typename T> 00456 inline 00457 void Parameters::insert (const std::string &name) 00458 { 00459 if (!this->have_parameter<T>(name)) 00460 _values[name] = new Parameter<T>; 00461 00462 set_attributes(name, true); 00463 } 00464 00465 00466 template <typename T> 00467 inline 00468 T& Parameters::set (const std::string& name) 00469 { 00470 if (!this->have_parameter<T>(name)) 00471 _values[name] = new Parameter<T>; 00472 00473 set_attributes(name, false); 00474 00475 return libmesh_cast_ptr<Parameter<T>*>(_values[name])->set(); 00476 } 00477 00478 inline 00479 void Parameters::remove (const std::string& name) 00480 { 00481 Parameters::iterator it = _values.find(name); 00482 00483 if (it != _values.end()) 00484 { 00485 delete it->second; 00486 it->second = NULL; 00487 00488 _values.erase(it); 00489 } 00490 } 00491 00492 00493 00494 #ifdef LIBMESH_HAVE_RTTI 00495 template <typename T> 00496 inline 00497 unsigned int Parameters::n_parameters () const 00498 { 00499 unsigned int cnt = 0; 00500 00501 Parameters::const_iterator it = _values.begin(); 00502 const Parameters::const_iterator vals_end = _values.end(); 00503 00504 for (; it != vals_end; ++it) 00505 if (dynamic_cast<Parameter<T>*>(it->second) != NULL) 00506 cnt++; 00507 00508 return cnt; 00509 } 00510 #endif 00511 00512 inline 00513 Parameters::iterator Parameters::begin() 00514 { 00515 return _values.begin(); 00516 } 00517 00518 inline 00519 Parameters::const_iterator Parameters::begin() const 00520 { 00521 return _values.begin(); 00522 } 00523 00524 inline 00525 Parameters::iterator Parameters::end() 00526 { 00527 return _values.end(); 00528 } 00529 00530 inline 00531 Parameters::const_iterator Parameters::end() const 00532 { 00533 return _values.end(); 00534 } 00535 00536 //non-member scalar print function 00537 template<typename P> 00538 void print_helper(std::ostream& os, const P* param) 00539 { 00540 os << *param; 00541 } 00542 00543 //non-member vector print function 00544 template<typename P> 00545 void print_helper(std::ostream& os, const std::vector<P>* param) 00546 { 00547 for (unsigned int i=0; i<param->size(); ++i) 00548 os << (*param)[i] << " "; 00549 } 00550 00551 } // namespace libMesh 00552 00553 #endif // LIBMESH_PARAMETERS_H
Site Created By: libMesh Developers
Last modified: February 05 2013 19:54:48 UTC
Hosted By: