Flow123d
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 
10 namespace Input {
11 namespace Type {
12 
13 using std::string;
14 
16 : data_(boost::make_shared<SelectionData>("EmptySelection"))
17 {
18  close();
19 }
20 
21 
22 
24 : Scalar(other), data_(other.data_)
25 {
26  ASSERT( TypeBase::was_constructed(&other), "Trying to copy non-constructed Selection.\n");
27 }
28 
29 
30 
31 Selection::Selection(const string &name, const string &desc)
32 : data_(boost::make_shared<SelectionData>(name))
33 {
34  TypeBase::lazy_type_list().push_back( boost::make_shared<Selection>( *this) );
35  data_->description_=desc;
36 }
37 
38 
39 
40 Selection &Selection::add_value(const int value, const std::string &key, const std::string &description) {
41  if (is_finished())
42  xprintf(PrgErr, "Declaration of new name: %s in finished Selection type: %s\n", key.c_str(), type_name().c_str());
43 
44  data_->add_value(value, key, description);
45  return *this;
46 }
47 
48 
49 const Selection & Selection::close() const {
50  data_->finished=true;
51  return *this;
52 }
53 
54 
55 
56 bool Selection::valid_default(const string &str) const {
57  if (! has_name(str))
58  THROW( ExcWrongDefault() << EI_DefaultStr( str ) << EI_TypeName( type_name() + " with values: "+key_list() ));
59  return true;
60 }
61 
62 
63 bool Selection::is_finished() const {
64  return data_->finished;
65 }
66 
67 
68 string Selection::type_name() const {
69  return data_->type_name_;
70 }
71 
72 
73 string Selection::full_type_name() const {
74  return data_->type_name_;
75 }
76 
77 
78 
79 bool Selection::operator==(const TypeBase &other) const {
80  return typeid(*this) == typeid(other) && (type_name() == static_cast<const Selection *>(&other)->type_name());
81 }
82 
83 
84 
85 int Selection::name_to_int(const string &key) const {
87  KeyHash key_h = key_hash(key);
88  SelectionData::key_to_index_const_iter it = data_->key_to_index_.find(key_h);
89  if (it != data_->key_to_index_.end())
90  return (data_->keys_[it->second].value);
91  else
92  throw ExcSelectionKeyNotFound() << EI_KeyName(key) << EI_Selection(*this);
93 }
94 
95 
96 string Selection::int_to_name(const int &val) const {
98  auto it = data_->value_to_index_.find(val);
99  if (it != data_->value_to_index_.end())
100  return data_->keys_[it->second].key_;
101  else
102  throw ExcSelectionValueNotFound() << EI_Value(val) << EI_Selection(*this);
103 }
104 
105 
107 {
108  for (auto it = sel.begin(); it != sel.end(); ++it)
109  {
110  int value = it->value;
111  while (data_->value_to_index_.find(value) != data_->value_to_index_.end()) value++;
112  add_value(value, it->key_, it->description_);
113  }
114 
115  return *this;
116 }
117 
118 
119 
120 int Selection::from_default(const string &str) const {
121  try {
122  return name_to_int(str);
123  } catch (ExcSelectionKeyNotFound &e) {
124  THROW( ExcWrongDefault() << EI_DefaultStr( str ) << EI_TypeName( type_name() + " with values: "+key_list() ));
125  }
126  return -1;
127 }
128 
129 
130 string Selection::key_list() const {
131  ostringstream os;
132  for(unsigned int i=0; i<size(); i++) os << "'" <<data_->keys_[i].key_ << "' ";
133  return os.str();
134 }
135 
136 
137 
138 void Selection::SelectionData::add_value(const int value, const std::string &key, const std::string &description) {
139  KeyHash key_h = TypeBase::key_hash(key);
140  if (key_to_index_.find(key_h) != key_to_index_.end()) {
141  xprintf(PrgErr, "Name '%s' already exists in Selection: %s\n", key.c_str(), type_name_.c_str());
142  return;
143  }
145  if (it != value_to_index_.end()) {
146  xprintf(
147  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());
148  return;
149  }
150 
151  unsigned int new_idx = key_to_index_.size();
152  key_to_index_.insert(std::make_pair(key_h, new_idx));
153  value_to_index_.insert(std::make_pair(value, new_idx));
154 
155  Key tmp_key = { new_idx, key, description, value };
156  keys_.push_back(tmp_key);
157 }
158 
159 
160 
161 
162 
163 } // closing namespace Type
164 } // close namespace Input