Reaktoro 
A unified framework for modeling chemically reactive systems
SetUtils.hxx
1 // Reaktoro is a unified framework for modeling chemically reactive systems.
2 //
3 // Copyright (C) 2014-2015 Allan Leal
4 //
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See The
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18 namespace Reaktoro {
19 
20 template<typename T>
21 auto index(const T& value, const std::vector<T>& values) -> Index
22 {
23  return std::find(values.begin(), values.end(), value) - values.begin();
24 }
25 
26 inline auto index(const std::string& word, const std::vector<std::string>& strings) -> Index
27 {
28  return index<std::string>(word, strings);
29 }
30 
31 template<typename NamedValues>
32 auto index(const std::string& name, const NamedValues& values) -> Index
33 {
34  Index idx = 0;
35  for(const auto& value : values)
36  if(value.name() == name) return idx; else ++idx;
37  return idx;
38 }
39 
40 template<typename NamedValue, typename NamedValues>
41 auto index(const NamedValue& value, const NamedValues& values) -> Index
42 {
43  return index(value.name(), values);
44 }
45 
46 template<typename Names, typename NamedValues>
47 auto indexAny(const Names& names, const NamedValues& values) -> Index
48 {
49  for(auto& name : names)
50  {
51  const Index i = index(name, values);
52  if(i < values.size())
53  return i;
54  }
55  return values.size();
56 }
57 
58 template<typename NamedValues>
59 auto indices(const std::vector<std::string>& names, const NamedValues& values) -> Indices
60 {
61  Indices idxs;
62  idxs.reserve(names.size());
63  for(const auto& name : names)
64  idxs.push_back(index(name, values));
65  return idxs;
66 }
67 
68 template<typename NamedValues>
69 auto indices(const NamedValues& subvalues, const NamedValues& values) -> Indices
70 {
71  Indices idxs;
72  idxs.reserve(subvalues.size());
73  for(const auto& value : subvalues)
74  idxs.push_back(index(value, values));
75  return idxs;
76 }
77 
78 inline auto indices(const std::vector<std::string>& words, const std::vector<std::string>& strings) -> Indices
79 {
81  indices.reserve(words.size());
82  for(const std::string iter : words)
83  indices.push_back(index(iter, strings));
84 
85  return indices;
86 }
87 
88 template<typename NamedValues>
89 auto contained(const std::string& name, const NamedValues& values) -> bool
90 {
91  return index(name, values) < values.size();
92 }
93 
94 template<typename Container>
95 auto contained(const typename Container::value_type& value, const Container& values) -> bool
96 {
97  return std::count(values.begin(), values.end(), value);
98 }
99 
100 template<typename Container>
101 auto contained(const Container& values1, const Container& values2) -> bool
102 {
103  for(const auto& value : values1)
104  if(!contained(value, values2))
105  return false;
106  return true;
107 }
108 
109 template<typename T>
110 auto unify(const std::vector<T>& values1, const std::vector<T>& values2) -> std::vector<T>
111 {
112  std::set<T> set;
113 
114  set.insert(values1.begin(), values1.end());
115  set.insert(values2.begin(), values2.end());
116 
117  return std::vector<T>(set.begin(), set.end());
118 }
119 
120 template<typename T>
121 auto intersect(const std::vector<T>& values1, const std::vector<T>& values2) -> std::vector<T>
122 {
123  std::vector<T> intersection;
124 
125  for(const T& value : values1)
126  if(contained(value, values2))
127  intersection.push_back(value);
128 
129  return intersection;
130 }
131 
132 template<typename T>
133 auto difference(const std::vector<T>& values1, const std::vector<T>& values2) -> std::vector<T>
134 {
135  std::vector<T> diff;
136 
137  for(const T& value : values1)
138  if(!contained(value, values2))
139  diff.push_back(value);
140 
141  return diff;
142 }
143 
144 template<typename T>
145 auto emptyIntersection(const std::vector<T>& values1, const std::vector<T>& values2) -> bool
146 {
147  for(const T& value : values1)
148  if(contained(value, values2))
149  return false;
150  return true;
151 }
152 
153 template<typename T>
154 auto emptyDifference(const std::vector<T>& values1, const std::vector<T>& values2) -> bool
155 {
156  for(const T& value : values1)
157  if(!contained(value, values2))
158  return false;
159  return true;
160 }
161 
162 template<typename Container>
163 auto equal(const Container& values1, const Container& values2) -> bool
164 {
165  if(values1.size() != values2.size())
166  return false;
167  for(const auto& value : values1)
168  if(!contained(value, values2))
169  return false;
170  return true;
171 }
172 
173 template<typename Container>
174 auto isunique(Container values) -> bool
175 {
176  std::set<Index> tmp(values.begin(), values.end());
177  return tmp.size() == values.size();
178 }
179 
180 template<typename T>
181 auto unique(std::vector<T> values) -> std::vector<T>
182 {
183  auto it = std::unique(values.begin(), values.end());
184 
185  values.resize(std::distance(values.begin(), it));
186 
187  return values;
188 }
189 
190 template<typename T>
191 auto range(T first, T last, T step) -> std::vector<T>
192 {
193  unsigned size = unsigned((last - first)/step);
194  std::vector<T> range(size);
195  for(unsigned i = 0; i < size; ++i)
196  range[i] = first + i*step;
197  return range;
198 }
199 
200 template<typename T>
201 auto range(T first, T last) -> std::vector<T>
202 {
203  return range(first, last, static_cast<T>(1));
204 }
205 
206 template<typename T>
207 auto range(T last) -> std::vector<T>
208 {
209  return range(static_cast<T>(0), last, static_cast<T>(1));
210 }
211 
212 template<typename T, typename Predicate>
213 auto filter(const std::vector<T>& values, Predicate predicate) -> std::vector<T>
214 {
215  std::vector<T> list;
216  for(const T& value : values)
217  if(predicate(value))
218  list.push_back(value);
219  return list;
220 }
221 
222 template<typename T, typename Predicate>
223 auto remove(const std::vector<T>& values, Predicate predicate) -> std::vector<T>
224 {
225  std::vector<T> list;
226  for(const T& value : values)
227  if(!predicate(value))
228  list.push_back(value);
229  return list;
230 }
231 
232 template<typename T>
233 auto extract(const std::vector<T>& values, const Indices& indices) -> std::vector<T>
234 {
235  std::vector<T> extracted_values;
236 
237  for(const auto& idx : indices)
238  extracted_values.push_back(values[idx]);
239 
240  return extracted_values;
241 }
242 
243 template<typename Container>
244 auto min(const Container& values) -> typename Container::value_type
245 {
246  return *std::min_element(values.begin(), values.end());
247 }
248 
249 template<typename Container>
250 auto max(const Container& values) -> typename Container::value_type
251 {
252  return *std::max_element(values.begin(), values.end());
253 }
254 
255 } // namespace Reaktoro
256 
257 
auto indexAny(const Names &names, const NamedValues &values) -> Index
Return the index of the first entry in a container of named values with any of the given names...
Definition: SetUtils.hxx:47
std::vector< Index > Indices
Define a type that represents a collection of indices.
Definition: Index.hpp:29
auto index(const T &value, const std::vector< T > &values) -> Index
Find the index of a value in a container of values.
Definition: SetUtils.hxx:21
auto names(const NamedValues &values) -> std::vector< std::string >
Return the names of the entries in a container.
Definition: Utils.hxx:22
auto filter(const std::vector< T > &values, Predicate predicate) -> std::vector< T >
Filter the values that pass on the predicate.
Definition: SetUtils.hxx:213
auto extract(const std::vector< T > &values, const Indices &indices) -> std::vector< T >
Extract values from a vector given a list of indices.
Definition: SetUtils.hxx:233
auto intersect(const std::vector< T > &values1, const std::vector< T > &values2) -> std::vector< T >
Determine the intersection of two containers.
Definition: SetUtils.hxx:121
auto unique(std::vector< T > values) -> std::vector< T >
Create a container with unique values from another.
Definition: SetUtils.hxx:181
auto difference(const std::vector< T > &values1, const std::vector< T > &values2) -> std::vector< T >
Determine the difference of two containers.
Definition: SetUtils.hxx:133
auto equal(const Container &values1, const Container &values2) -> bool
Check if two containers are equal.
Definition: SetUtils.hxx:163
std::size_t Index
Define a type that represents an index.
Definition: Index.hpp:26
auto range(T first, T last, T step) -> std::vector< T >
Return a range of values.
Definition: SetUtils.hxx:191
auto unify(const std::vector< T > &values1, const std::vector< T > &values2) -> std::vector< T >
Determine the union of two containers.
Definition: SetUtils.hxx:110
auto indices(const std::vector< std::string > &names, const NamedValues &values) -> Indices
Return the indices of some entries in a container.
Definition: SetUtils.hxx:59
auto emptyIntersection(const std::vector< T > &values1, const std::vector< T > &values2) -> bool
Check if two containers have empty intersection.
Definition: SetUtils.hxx:145
auto contained(const typename Container::value_type &value, const Container &values) -> bool
Check if a value is contained in a container of values.
Definition: SetUtils.hxx:95
The namespace containing all components of the Reaktoro library.
Definition: ChemicalScalar.hpp:24
auto emptyDifference(const std::vector< T > &values1, const std::vector< T > &values2) -> bool
Check if two containers have empty difference.
Definition: SetUtils.hxx:154
auto isunique(Container values) -> bool
Check if a container has unique values.
Definition: SetUtils.hxx:174