16 const std::multimap<DB::SELECTION_TYPE, std::vector<std::string> >
17 traits<DB::SELECTION_TYPE>::strval = {
23 {
"CALCULATED",
"Calculated",
"calculated"}}};
32 #define INST_Selection(r, data, type) \
33 template class SelectionIterator<type, Selection<type>::base_iterator>; \
34 template class SelectionIterator<type, \
35 Selection<type>::base_const_iterator>; \
36 template class Selection<type>;
48 template <typename ObjType, typename IfConfigType<ObjType>::type * =
nullptr>
50 Database<ObjType> &db) {
51 for (
const auto &obj : db) {
52 m_data.insert(std::make_pair(obj.name(),
is_calculated(obj)));
59 template <typename ObjType, typename IfNotConfigType<ObjType>::type * =
nullptr>
61 Database<ObjType> &db) {
62 std::stringstream msg;
63 msg <<
"Selection 'CALCULATED' is not allowed for type: "
64 << traits<ObjType>::short_name;
65 throw std::runtime_error(msg.str());
73 template <
typename ObjType,
typename BaseIterator>
79 template <
typename ObjType,
typename BaseIterator>
86 template <
typename ObjType,
typename BaseIterator>
92 template <
typename ObjType,
typename BaseIterator>
95 : m_list(&_list), m_it(_it), m_selected_only(_selected_only) {
97 m_it->second ==
false) {
103 template <
typename ObjType,
typename BaseIterator>
106 while (m_selected_only && m_it != m_list->data().end() &&
107 m_it->second ==
false) {
113 template <
typename ObjType,
typename BaseIterator>
116 while (m_selected_only && m_it != m_list->data().begin() &&
117 m_it->second ==
false) {
123 template <
typename ObjType,
typename BaseIterator>
125 return *(m_list->db().find(m_it->first));
129 template <
typename ObjType,
typename BaseIterator>
138 template <
typename ObjType>
142 template <
typename ObjType>
144 fs::path selection_path)
147 template <
typename ObjType>
151 m_name(selection_path.string()) {
152 auto _match = matches<DB::SELECTION_TYPE>(selection_path.string());
154 if (_match.size() == 1 || selection_path.empty()) {
156 selection_path.empty() ? DB::SELECTION_TYPE::MASTER : *_match.begin();
158 if (sel == DB::SELECTION_TYPE::MASTER) {
159 fs::path master_selection_path;
161 master_selection_path =
162 primclex().dir().template master_selection<ObjType>();
164 if (!master_selection_path.empty() && fs::exists(master_selection_path)) {
165 fs::ifstream select_file(master_selection_path);
169 for (
const auto &obj : db()) {
170 m_data.insert(std::make_pair(obj.name(),
false));
173 }
else if (sel == DB::SELECTION_TYPE::NONE) {
174 for (
const auto &obj : db()) {
175 m_data.insert(std::make_pair(obj.name(),
false));
177 }
else if (sel == DB::SELECTION_TYPE::EMPTY) {
178 }
else if (sel == DB::SELECTION_TYPE::ALL) {
179 for (
const auto &obj : db()) {
180 m_data.insert(std::make_pair(obj.name(),
true));
182 }
else if (sel == DB::SELECTION_TYPE::CALCULATED) {
183 init_calculated(m_data, db());
186 if (!fs::exists(selection_path)) {
187 std::stringstream ss;
188 ss <<
"ERROR in parsing configuration selection name. \n"
189 <<
" " << singleline_help<DB::SELECTION_TYPE>() <<
"\n"
190 <<
" Received: '" << selection_path <<
"'\n"
191 <<
" No file named '" << selection_path <<
"'.";
192 throw std::runtime_error(ss.str());
194 m_name = fs::absolute(selection_path).string();
195 if (selection_path.extension() ==
".json" ||
196 selection_path.extension() ==
".JSON") {
199 fs::ifstream select_file(selection_path);
206 template <
typename ObjType>
211 template <
typename ObjType>
214 throw std::runtime_error(
215 "Error in Selection<ObjType>::db(): Database pointer invalid");
220 template <
typename ObjType>
223 return boost::make_iterator_range(
iterator(*
this, m_data.begin(),
false),
224 iterator(*
this, m_data.end(),
false));
227 template <
typename ObjType>
230 return boost::make_iterator_range(
235 template <
typename ObjType>
238 return boost::make_iterator_range(
iterator(*
this, m_data.begin(),
true),
239 iterator(*
this, m_data.end(),
true));
242 template <
typename ObjType>
245 return boost::make_iterator_range(
const_iterator(*
this, m_data.begin(),
true),
249 template <
typename ObjType>
254 template <
typename ObjType>
259 template <
typename ObjType>
261 return m_data.
size();
264 template <
typename ObjType>
266 return m_col_headers;
269 template <
typename ObjType>
274 template <
typename ObjType>
280 template <
typename ObjType>
282 auto it = m_data.find(db().
name(name_or_alias));
283 if (it == m_data.end()) {
290 template <
typename ObjType>
292 const std::string &criteria) {
294 if (criteria.size()) {
296 auto it = all().begin();
297 auto end = all().end();
298 for (; it != end; ++it) {
300 select_stream << tformat(*it);
301 if (select_stream.
fail()) {
302 err_log() <<
"Warning: Unable to apply criteria \"" << criteria
307 it.is_selected() = select_stream.
value();
310 }
catch (std::exception &e) {
311 throw std::runtime_error(
312 std::string(
"Failure to select using criteria \"") + criteria +
321 template <
typename ObjType>
323 const std::string &criteria,
bool value) {
325 if (criteria.size()) {
327 auto it = all().begin();
328 auto end = all().end();
329 for (; it != end; ++it) {
330 if (it.is_selected() == value) {
334 if (select_stream.
fail()) {
335 err_log() <<
"Warning: Unable to apply criteria \"" << criteria
341 select_stream << tformat(*it);
342 if (select_stream.
value()) {
343 it.is_selected() = value;
347 auto it = all().begin();
348 auto end = all().end();
349 for (; it != end; ++it) {
350 it.is_selected() = value;
353 }
catch (std::exception &e) {
354 throw std::runtime_error(
355 std::string(
"Failure to select using criteria \"") + criteria +
364 template <
typename ObjType>
366 std::string tname_or_alias;
369 if (_input.peek() ==
'#') {
372 _input >> tname_or_alias;
373 _input >> tname_or_alias;
374 std::getline(_input, tname_or_alias,
'\n');
375 m_col_headers.clear();
376 boost::split(m_col_headers, tname_or_alias, boost::is_any_of(
" \t"),
377 boost::token_compress_on);
380 while (_input >> tname_or_alias >> tselect) {
383 if (db().
find(db().
name(tname_or_alias)) == db().end()) {
386 m_data[db().name(tname_or_alias)] = tselect;
392 template <
typename ObjType>
395 std::cerr <<
"CRITICAL ERROR: Unable to initialize a Selection from passed "
398 <<
" JSON input must be an array of records."
400 <<
" Exiting..." << std::endl;
408 std::set<std::string> prop_set;
411 for (
Index i = 0; i < _json.
size(); i++) {
412 auto it(_json[i].cbegin()), it_end(_json[i].cend());
414 contains_name =
false;
417 for (; it != it_end; ++it) {
419 if (it.name() ==
"name" || it.name() ==
"alias" ||
420 it.name() ==
"alias_or_name" || it.name() ==
"configname") {
421 tname = db().name(it->get<std::string>());
422 contains_name =
true;
423 }
else if (it.name() ==
"selected") {
424 tselected = it->get<
bool>();
426 prop_set.insert(it.name());
430 if (!contains_name) {
431 throw std::runtime_error(
432 std::string(
"CRITICAL ERROR: Field 'name' is missing from ") +
434 " of json Array passed to Selection::from_json()." +
435 " This field is required.");
438 m_data[tname] = tselected;
441 m_col_headers = std::vector<std::string>(prop_set.begin(), prop_set.end());
447 template <
typename ObjType>
450 bool only_selected)
const {
454 alias_or_name<ObjType>(),
462 _json = tformat(all().begin(), all().end());
469 template <
typename ObjType>
471 std::ostream &_out,
bool only_selected)
const {
473 alias_or_name<ObjType>(),
481 _out << tformat(all().begin(), all().end());
486 template <
typename ObjType>
488 const fs::path &_out_path,
bool write_json,
489 bool only_selected)
const {
490 fs::path out_path(_out_path);
491 auto _matches = matches<DB::SELECTION_TYPE>(out_path.string());
492 if (_matches.size() == 1 && *_matches.begin() == DB::SELECTION_TYPE::MASTER) {
493 out_path =
primclex().dir().template master_selection<ObjType>();
496 if (write_json || out_path.extension() ==
".json" ||
497 out_path.extension() ==
".JSON") {
499 this->
to_json(dict, json, only_selected);
507 this->print(dict, sout.
ofstream(), only_selected);
#define INST_Selection(r, data, type)
#define ENUM_JSON_IO_DEF(ENUM)
#define ENUM_IO_DEF(ENUM)
Returns true if configuration is specified in given selection (default: MASTER)
std::map< std::string, bool, Compare > map_type
Selection()
Default construct into invalid state.
void decrement()
boost::iterator_facade implementation
std::string name() const
Name of object the iterator points at.
bool equal(const SelectionIterator &B) const
boost::iterator_facade implementation
bool_type & is_selected()
Reference to value 'is_selected'.
void increment()
boost::iterator_facade implementation
CASM_TMP::ConstSwitch< std::is_same< BaseIterator, std::map< std::string, bool >::const_iterator >::value, bool > bool_type
const ObjType & dereference() const
boost::iterator_facade implementation
SelectionIterator()
Default constructor (equals end)
const Selection< ObjType > * m_list
PrimClex is the top-level data structure for a CASM project.
Write to a temporary file to ensure a good write, then rename.
void close()
Closes stream, and if not a failed write, removes "file" and renames "file.tmp" to "file".
void open(fs::path name, std::string tmp_ext="tmp")
Opens "file.tmp" for writing, with intended final target "file".
fs::ofstream & ofstream()
Access underlying stream.
bool is_array() const
Check if array type.
jsonParser & put_array()
Puts new empty JSON array.
void print(std::ostream &stream, unsigned int indent=2, unsigned int prec=12) const
Print json to stream.
std::string to_string(ENUM val)
Return string representation of enum class.
GenericDatumFormatter< std::string, ConfigEnumDataType > name()
GenericDatumFormatter< bool, ConfigEnumDataType > selected()
jsonParser & to_json(const ClexDescription &desc, jsonParser &json)
bool is_calculated(const ConfigType &config, std::string calctype="")
Return true if all required properties have been been calculated for the configuration.
void from_json(ClexDescription &desc, const jsonParser &json)
Iterator find(Iterator begin, Iterator end, const T &value, BinaryCompare q)
Equivalent to std::find(begin, end, value), but with custom comparison.
INDEX_TYPE Index
For long integer indexing:
T max(const T &A, const T &B)