Flow123d  jenkins-Flow123d-linux-release-multijob-282
type_selection.cc
Go to the documentation of this file.
1 /*
2  * type_selection.cc
3  *
4  * Created on: Aug 1, 2012
5  * Author: jb
6  */
7 
9 #include <boost/functional/hash.hpp>
10 
11 namespace Input {
12 namespace Type {
13 
14 using std::string;
15 
17 : data_(boost::make_shared<SelectionData>("EmptySelection"))
18 {
19  close();
20 }
21 
22 
23 
25 : Scalar(other), data_(other.data_)
26 {
27  ASSERT( TypeBase::was_constructed(&other), "Trying to copy non-constructed Selection.\n");
28 }
29 
30 
31 
32 Selection::Selection(const string &name, const string &desc)
33 : data_(boost::make_shared<SelectionData>(name))
34 {
35  TypeBase::lazy_type_list().push_back( boost::make_shared<Selection>( *this) );
36  data_->description_=desc;
37 }
38 
39 
40 
41 Selection &Selection::add_value(const int value, const std::string &key, const std::string &description) {
42  if (is_finished())
43  xprintf(PrgErr, "Declaration of new name: %s in finished Selection type: %s\n", key.c_str(), type_name().c_str());
44 
45  data_->add_value(value, key, description);
46  return *this;
47 }
48 
49 
50 const Selection & Selection::close() const {
51  data_->finished=true;
52  return *this;
53 }
54 
55 
56 
57 std::size_t Selection::content_hash() const
58 {
59  std::size_t seed=0;
60  boost::hash_combine(seed, "Selection");
61  boost::hash_combine(seed, type_name());
62  boost::hash_combine(seed, data_->description_);
63  for( Key &key : data_->keys_) {
64  boost::hash_combine(seed, key.key_);
65  boost::hash_combine(seed, key.description_);
66  boost::hash_combine(seed, key.value);
67  }
68  return seed;
69 }
70 
71 
72 
73 bool Selection::valid_default(const string &str) const {
74  if (! has_name(str))
75  THROW( ExcWrongDefault() << EI_DefaultStr( str ) << EI_TypeName( type_name() + " with values: "+key_list() ));
76  return true;
77 }
78 
79 
80 bool Selection::is_finished() const {
81  return data_->finished;
82 }
83 
84 
85 string Selection::type_name() const {
86  return data_->type_name_;
87 }
88 
89 
90 string Selection::full_type_name() const {
91  return data_->type_name_;
92 }
93 
94 
95 
96 bool Selection::operator==(const TypeBase &other) const {
97  return typeid(*this) == typeid(other) && (type_name() == static_cast<const Selection *>(&other)->type_name());
98 }
99 
100 
101 
102 int Selection::name_to_int(const string &key) const {
103  finished_check();
104  KeyHash key_h = key_hash(key);
105  SelectionData::key_to_index_const_iter it = data_->key_to_index_.find(key_h);
106  if (it != data_->key_to_index_.end())
107  return (data_->keys_[it->second].value);
108  else
109  throw ExcSelectionKeyNotFound() << EI_KeyName(key) << EI_Selection(*this);
110 }
111 
112 
113 string Selection::int_to_name(const int &val) const {
114  finished_check();
115  auto it = data_->value_to_index_.find(val);
116  if (it != data_->value_to_index_.end())
117  return data_->keys_[it->second].key_;
118  else
119  throw ExcSelectionValueNotFound() << EI_Value(val) << EI_Selection(*this);
120 }
121 
122 
124 {
125  for (auto it = sel.begin(); it != sel.end(); ++it)
126  {
127  int value = it->value;
128  while (data_->value_to_index_.find(value) != data_->value_to_index_.end()) value++;
129  add_value(value, it->key_, it->description_);
130  }
131 
132  return *this;
133 }
134 
135 
136 
137 int Selection::from_default(const string &str) const {
138  try {
139  return name_to_int(str);
140  } catch (ExcSelectionKeyNotFound &e) {
141  THROW( ExcWrongDefault() << EI_DefaultStr( str ) << EI_TypeName( type_name() + " with values: "+key_list() ));
142  }
143  return -1;
144 }
145 
146 
147 string Selection::key_list() const {
148  ostringstream os;
149  for(unsigned int i=0; i<size(); i++) os << "'" <<data_->keys_[i].key_ << "' ";
150  return os.str();
151 }
152 
153 
154 
155 void Selection::SelectionData::add_value(const int value, const std::string &key, const std::string &description) {
156  KeyHash key_h = TypeBase::key_hash(key);
157  if (key_to_index_.find(key_h) != key_to_index_.end()) {
158  xprintf(PrgErr, "Name '%s' already exists in Selection: %s\n", key.c_str(), type_name_.c_str());
159  return;
160  }
162  if (it != value_to_index_.end()) {
163  xprintf(
164  PrgErr, "Value %d of new name '%s' conflicts with value %d of previous name '%s' in Selection: '%s'.\n", value, key.c_str(), keys_[it->second].value, keys_[it->second].key_.c_str(), type_name_.c_str());
165  return;
166  }
167 
168  unsigned int new_idx = key_to_index_.size();
169  key_to_index_.insert(std::make_pair(key_h, new_idx));
170  value_to_index_.insert(std::make_pair(value, new_idx));
171 
172  Key tmp_key = { new_idx, key, description, value };
173  keys_.push_back(tmp_key);
174 }
175 
176 
177 
178 
179 
180 } // closing namespace Type
181 } // close namespace Input
std::map< int, unsigned int >::const_iterator value_to_index_const_iter
Base of classes for declaring structure of the input data.
Definition: type_base.hh:63
unsigned int size() const
std::vector< Key > keys_
Vector of values of the Selection.
int from_default(const string &str) const
string int_to_name(const int &value) const
string desc() const
Definition: type_base.cc:73
int name_to_int(const string &key) const
virtual string full_type_name() const
Implements TypeBase::full_type_name.
Selection & copy_values(const Selection &sel)
static LazyTypeVector & lazy_type_list()
Definition: type_base.cc:81
Base of all scalar types.
Definition: type_base.hh:317
static KeyHash key_hash(const string &str)
Hash function.
Definition: type_base.hh:171
void add_value(const int value, const std::string &key, const std::string &description)
virtual string type_name() const
Implements TypeBase::type_name.
bool has_name(const string &key) const
virtual bool operator==(const TypeBase &other) const
Implements TypeBase::operator== compare also Selection names.
virtual bool valid_default(const string &str) const
Implements Type::TypeBase::valid_defaults.
#define ASSERT(...)
Definition: global_defs.h:121
Selection & add_value(const int value, const std::string &key, const std::string &description="")
#define xprintf(...)
Definition: system.hh:100
static bool was_constructed(const TypeBase *ptr)
Definition: type_base.cc:124
keys_const_iterator end() const
std::map< int, unsigned int > value_to_index_
Map : valid value to index.
boost::shared_ptr< SelectionData > data_
Handle to actual Selection data.
const Selection & close() const
std::map< KeyHash, unsigned int >::const_iterator key_to_index_const_iter
Definition: system.hh:72
std::size_t content_hash() const override
virtual bool is_finished() const
Implements TypeBase::is_finished.
void finished_check() const
std::map< KeyHash, unsigned int > key_to_index_
Map : valid value name to index.
string type_name_
Name of the Selection.
keys_const_iterator begin() const
string key_list() const
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:34
Template for classes storing finite set of named values.