parameters.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2018 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 #ifndef LIBMESH_PARAMETERS_H
21 #define LIBMESH_PARAMETERS_H
22 
23 // C++ includes
24 #include <typeinfo>
25 #include <string>
26 #include <map>
27 
28 // Local includes
29 #include "libmesh/libmesh_common.h"
31 #include "libmesh/print_trace.h"
32 
33 // C++ includes
34 #include <cstddef>
35 #include <map>
36 #include <string>
37 #include <typeinfo>
38 #include <sstream>
39 
40 namespace libMesh
41 {
45 template<typename P>
46 void print_helper(std::ostream & os, const P * param);
47 
48 template<typename P>
49 void print_helper(std::ostream & os, const std::vector<P> * param);
50 
51 template<typename P>
52 void print_helper(std::ostream & os, const std::vector<std::vector<P>> * param);
53 
64 {
65 public:
66 
70  Parameters () {}
71 
75  Parameters (const Parameters &);
76 
80  virtual ~Parameters ();
81 
86  virtual Parameters & operator= (const Parameters & source);
87 
93  virtual Parameters & operator+= (const Parameters & source);
94 
102  template <typename T>
103  bool have_parameter (const std::string &) const;
104 
109  template <typename T>
110  const T & get (const std::string &) const;
111 
117  template <typename T>
118  void insert (const std::string &);
119 
126  template <typename T>
127  T & set (const std::string &);
128 
133  virtual void set_attributes(const std::string &, bool /*inserted_only*/) {}
134 
138  void remove (const std::string &);
139 
143  std::size_t n_parameters () const { return _values.size(); }
144 
145 #ifdef LIBMESH_HAVE_RTTI
146 
149  template <typename T>
150  unsigned int n_parameters () const;
151 #endif // LIBMESH_HAVE_RTTI
152 
156  virtual void clear ();
157 
161  void print (std::ostream & os=libMesh::out) const;
162 
166  class Value : public ReferenceCountedObject<Value>
167  {
168  public:
169 
173  virtual ~Value() {}
174 
175 #ifdef LIBMESH_HAVE_RTTI
176 
180  virtual std::string type () const = 0;
181 #endif // LIBMESH_HAVE_RTTI
182 
187  virtual void print(std::ostream &) const = 0;
188 
193  virtual Value * clone () const = 0;
194  };
195 
200  template <typename T>
201  class Parameter : public Value
202  {
203  public:
204 
208  const T & get () const { return _value; }
209 
213  T & set () { return _value; }
214 
215 #ifdef LIBMESH_HAVE_RTTI
216 
219  virtual std::string type () const;
220 #endif // LIBMESH_HAVE_RTTI
221 
225  virtual void print(std::ostream &) const;
226 
230  virtual Value * clone () const;
231 
232  private:
237  };
238 
242  typedef std::map<std::string, Value *>::iterator iterator;
243 
247  typedef std::map<std::string, Value *>::const_iterator const_iterator;
248 
252  iterator begin();
253 
257  const_iterator begin() const;
258 
262  iterator end();
263 
267  const_iterator end() const;
268 
269 protected:
270 
274  std::map<std::string, Value *> _values;
275 
276 };
277 
278 // ------------------------------------------------------------
279 // Parameters::Parameter<> class inline methods
280 
281 // This only works with Run-Time Type Information, even though
282 // typeid(T) *should* be determinable at compile time regardless...
283 #ifdef LIBMESH_HAVE_RTTI
284 template <typename T>
285 inline
286 std::string Parameters::Parameter<T>::type () const
287 {
288  return demangle(typeid(T).name());
289 }
290 #endif
291 
292 template <typename T>
293 inline
294 void Parameters::Parameter<T>::print (std::ostream & os) const
295 {
296  // Call helper function overloaded for basic scalar and vector types
297  print_helper(os, static_cast<const T *>(&_value));
298 }
299 
300 template <typename T>
301 inline
303 {
304  Parameter<T> * copy = new Parameter<T>;
305 
306  libmesh_assert(copy);
307 
308  copy->_value = _value;
309 
310  return copy;
311 }
312 
313 
314 // ------------------------------------------------------------
315 // Parameters class inline methods
316 inline
317 void Parameters::clear () // since this is inline we must define it
318 { // before its first use (for some compilers)
319  while (!_values.empty())
320  {
321  Parameters::iterator it = _values.begin();
322 
323  delete it->second;
324  it->second = libmesh_nullptr;
325 
326  _values.erase(it);
327  }
328 }
329 
330 
331 
332 inline
334 {
335  this->clear();
336  *this += source;
337 
338  return *this;
339 }
340 
341 inline
343 {
344  for (Parameters::const_iterator it = source._values.begin();
345  it != source._values.end(); ++it)
346  {
347  if (_values.find(it->first) != _values.end())
348  delete _values[it->first];
349  _values[it->first] = it->second->clone();
350  }
351 
352  return *this;
353 }
354 
355 inline
357 {
358  *this = p;
359 }
360 
361 
362 
363 inline
365 {
366  this->clear ();
367 }
368 
369 
370 
371 inline
372 void Parameters::print (std::ostream & os) const
373 {
374  Parameters::const_iterator it = _values.begin();
375 
376  os << "Name\t Type\t Value\n"
377  << "---------------------\n";
378  while (it != _values.end())
379  {
380  os << " " << it->first
381 #ifdef LIBMESH_HAVE_RTTI
382  << "\t " << it->second->type()
383 #endif // LIBMESH_HAVE_RTTI
384  << "\t "; it->second->print(os);
385  os << '\n';
386 
387  ++it;
388  }
389 }
390 
391 
392 
393 // Declare this now that Parameters::print() is defined.
394 // By declaring this early we can use it in subsequent
395 // methods. Required for gcc-4.0.2 -- 11/30/2005, BSK
396 inline
397 std::ostream & operator << (std::ostream & os, const Parameters & p)
398 {
399  p.print(os);
400  return os;
401 }
402 
403 
404 
405 template <typename T>
406 inline
407 bool Parameters::have_parameter (const std::string & name) const
408 {
409  Parameters::const_iterator it = _values.find(name);
410 
411  if (it != _values.end())
412 #ifdef LIBMESH_HAVE_RTTI
413  if (dynamic_cast<const Parameter<T> *>(it->second) != libmesh_nullptr)
414 #else // LIBMESH_HAVE_RTTI
415  if (cast_ptr<const Parameter<T> *>(it->second) != libmesh_nullptr)
416 #endif // LIBMESH_HAVE_RTTI
417  return true;
418 
419  return false;
420 }
421 
422 
423 
424 template <typename T>
425 inline
426 const T & Parameters::get (const std::string & name) const
427 {
428  if (!this->have_parameter<T>(name))
429  {
430  std::ostringstream oss;
431 
432  oss << "ERROR: no";
433 #ifdef LIBMESH_HAVE_RTTI
434  oss << ' ' << demangle(typeid(T).name());
435 #endif
436  oss << " parameter named \""
437  << name << "\" found.\n\n"
438  << "Known parameters:\n"
439  << *this;
440 
441  libmesh_error_msg(oss.str());
442  }
443 
444  Parameters::const_iterator it = _values.find(name);
445 
446  libmesh_assert(it != _values.end());
447  libmesh_assert(it->second);
448 
449  return cast_ptr<Parameter<T> *>(it->second)->get();
450 }
451 
452 template <typename T>
453 inline
454 void Parameters::insert (const std::string & name)
455 {
456  if (!this->have_parameter<T>(name))
457  _values[name] = new Parameter<T>;
458 
459  set_attributes(name, true);
460 }
461 
462 
463 template <typename T>
464 inline
465 T & Parameters::set (const std::string & name)
466 {
467  if (!this->have_parameter<T>(name))
468  _values[name] = new Parameter<T>;
469 
470  set_attributes(name, false);
471 
472  return cast_ptr<Parameter<T> *>(_values[name])->set();
473 }
474 
475 inline
476 void Parameters::remove (const std::string & name)
477 {
478  Parameters::iterator it = _values.find(name);
479 
480  if (it != _values.end())
481  {
482  delete it->second;
483  it->second = libmesh_nullptr;
484 
485  _values.erase(it);
486  }
487 }
488 
489 
490 
491 #ifdef LIBMESH_HAVE_RTTI
492 template <typename T>
493 inline
494 unsigned int Parameters::n_parameters () const
495 {
496  unsigned int cnt = 0;
497 
498  Parameters::const_iterator it = _values.begin();
499  const Parameters::const_iterator vals_end = _values.end();
500 
501  for (; it != vals_end; ++it)
502  if (dynamic_cast<Parameter<T> *>(it->second) != libmesh_nullptr)
503  cnt++;
504 
505  return cnt;
506 }
507 #endif
508 
509 inline
511 {
512  return _values.begin();
513 }
514 
515 inline
517 {
518  return _values.begin();
519 }
520 
521 inline
523 {
524  return _values.end();
525 }
526 
527 inline
529 {
530  return _values.end();
531 }
532 
533 //non-member scalar print function
534 template<typename P>
535 void print_helper(std::ostream & os, const P * param)
536 {
537  os << *param;
538 }
539 
540 template<>
541 inline
542 void print_helper(std::ostream & os, const char * param)
543 {
544  // Specialization so that we don't print out unprintable characters
545  os << static_cast<int>(*param);
546 }
547 
548 template<>
549 inline
550 void print_helper(std::ostream & os, const unsigned char * param)
551 {
552  // Specialization so that we don't print out unprintable characters
553  os << static_cast<int>(*param);
554 }
555 
556 //non-member vector print function
557 template<typename P>
558 void print_helper(std::ostream & os, const std::vector<P> * param)
559 {
560  for (std::size_t i=0; i<param->size(); ++i)
561  os << (*param)[i] << " ";
562 }
563 
564 //non-member vector<vector> print function
565 template<typename P>
566 void print_helper(std::ostream & os, const std::vector<std::vector<P>> * param)
567 {
568  for (std::size_t i=0; i<param->size(); ++i)
569  for (std::size_t j=0; j<(*param)[i].size(); ++j)
570  os << (*param)[i][j] << " ";
571 }
572 
573 } // namespace libMesh
574 
575 #endif // LIBMESH_PARAMETERS_H
std::string name(const ElemQuality q)
Definition: elem_quality.C:39
std::size_t n_parameters() const
Definition: parameters.h:143
std::map< std::string, Value * >::const_iterator const_iterator
Definition: parameters.h:247
virtual ~Parameters()
Definition: parameters.h:364
virtual Value * clone() const =0
void print_helper(std::ostream &os, const P *param)
Definition: parameters.h:535
std::map< std::string, Value * >::iterator iterator
Definition: parameters.h:242
Tnew cast_ptr(Told *oldvar)
const class libmesh_nullptr_t libmesh_nullptr
const T & get(const std::string &) const
Definition: parameters.h:426
virtual std::string type() const =0
virtual void print(std::ostream &) const
Definition: parameters.h:294
virtual Parameters & operator+=(const Parameters &source)
Definition: parameters.h:342
virtual Parameters & operator=(const Parameters &source)
Definition: parameters.h:333
virtual std::string type() const
Definition: parameters.h:286
virtual void print(std::ostream &) const =0
void remove(const std::string &)
Definition: parameters.h:476
iterator begin()
Definition: parameters.h:510
std::string demangle(const char *name)
Definition: print_trace.C:250
std::map< std::string, Value * > _values
Definition: parameters.h:274
void print(std::ostream &os=libMesh::out) const
Definition: parameters.h:372
T & set(const std::string &)
Definition: parameters.h:465
virtual void clear()
Definition: parameters.h:317
bool have_parameter(const std::string &) const
Definition: parameters.h:407
void insert(const std::string &)
Definition: parameters.h:454
virtual Value * clone() const
Definition: parameters.h:302
OStreamProxy out(std::cout)
std::ostream & operator<<(std::ostream &os, const FEAbstract &fe)
Definition: fe_abstract.C:782
virtual void set_attributes(const std::string &, bool)
Definition: parameters.h:133