25#include <boost/algorithm/string/classification.hpp>
26#include <boost/algorithm/string/join.hpp>
27#include <boost/algorithm/string/predicate.hpp>
28#include <boost/algorithm/string/split.hpp>
29#include <boost/lexical_cast.hpp>
31#if __cplusplus <= 199711L
32#define MEM_FN std::mem_fun_ref
34#define MEM_FN std::mem_fn
49template<
class Target,
class Source>
inline Target
51{
return boost::lexical_cast<Target>(arg); }
61template<
class Source>
inline std::string
63{
return boost::lexical_cast<std::string>(arg); }
76template<
class Source>
inline std::string
79 std::ostringstream output;
80 output << std::setprecision(precision) << std::scientific << arg;
89{
return str.find_first_not_of(
" \t\n\v\f\r") == std::string::npos; }
94 std::string str_upper(str.length(),
char());
95 std::transform(str.begin(), str.end(), str_upper.begin(),
96 static_cast<int (*)(
int)
>(std::toupper));
103 const std::size_t startpos = str.find_first_not_of(
" \t\n\v\f\r");
104 if (startpos != std::string::npos) str.erase(0, startpos);
111 const std::size_t endpos = str.find_last_not_of(
" \t\n\v\f\r");
112 if (endpos != std::string::npos) str.erase(endpos + 1);
125inline std::ostream&
operator<<(std::ostream& os,
const Line& line);
126inline std::ostream&
operator<<(std::ostream& os,
const Block& block);
127inline std::ostream&
operator<<(std::ostream& os,
const Coll& coll);
128inline std::ostream&
operator<<(std::ostream& os,
const Key& key);
225 std::string field_str =
to_string(field);
227 if (field_str.empty())
return *
this;
230 {
back() += field_str; }
234 impl_.push_back(field_str);
269 str(
const std::string& line)
272 static const std::string whitespace =
" \t\v\f\r";
273 const std::size_t last_non_ws =
274 line.substr(0, line.find(
'\n')).find_last_not_of(whitespace);
275 if (last_non_ws == std::string::npos)
return *
this;
277 const std::string trimmed_line = line.substr(0, last_non_ws + 1);
278 const std::size_t comment_pos = trimmed_line.find(
'#');
279 const std::string
data = trimmed_line.substr(0, comment_pos);
281 std::size_t pos1 =
data.find_first_not_of(whitespace, 0);
282 std::size_t pos2 =
data.find_first_of(whitespace, pos1);
284 while (pos1 != std::string::npos)
286 impl_.push_back(
data.substr(pos1, pos2 - pos1));
289 pos1 =
data.find_first_not_of(whitespace, pos2);
290 pos2 =
data.find_first_of(whitespace, pos1);
293 if (comment_pos != std::string::npos)
295 impl_.push_back(trimmed_line.substr(comment_pos));
305 if (
empty())
return "";
307 std::ostringstream output;
308 int length = 0, spaces = 0;
311 std::vector<std::size_t>::const_iterator column =
columns_.begin();
312 for (; field !=
end() && column !=
columns_.end(); ++field, ++column)
314 spaces = std::max(0,
static_cast<int>(*column) - length + 1);
315 length += spaces + field->length();
317 output << std::setw(spaces) <<
" " << *field;
319 return output.str().substr(1);
357 {
return impl_.at(n); }
367 {
return impl_.at(n); }
374 {
return impl_.front(); }
382 {
return impl_.front(); }
389 {
return impl_.back(); }
397 {
return impl_.back(); }
406 {
return impl_.begin(); }
415 {
return impl_.begin(); }
424 {
return impl_.begin(); }
433 {
return impl_.end(); }
442 {
return impl_.end(); }
451 {
return impl_.end(); }
459 {
return impl_.rbegin(); }
468 {
return impl_.rbegin(); }
477 {
return impl_.rbegin(); }
486 {
return impl_.rend(); }
495 {
return impl_.rend(); }
504 {
return impl_.rend(); }
514 if (
size() < 2)
return false;
537 {
return impl_.size(); }
549 {
return impl_.max_size(); }
554 {
return impl_.empty(); }
584 std::size_t pos1 = 0, pos2 = 0;
589 pos2 = pos1 + field->length();
592 if (++field ==
end())
return;
595 pos2 = pos1 + field->length();
601 pos2 = pos1 + field->length();
607 pos2 = pos1 + field->length();
611 while (++field !=
end())
615 pos2 = pos1 + field->length();
659 static const std::size_t specifier_length = 5;
660 if (field.length() != specifier_length)
return false;
663 return (field_upper ==
"BLOCK") || (field_upper ==
"DECAY");
668 {
return !field.empty() && field[0] ==
'#'; }
670 template<
class T>
Line&
673 static const int digits = std::numeric_limits<T>::digits10;
679 {
return !field.empty() && (field[0] ==
'-' || field[0] ==
'+'); }
689template<>
inline Line&
690Line::operator<< <float>(
const float& number)
696template<>
inline Line&
697Line::operator<< <double>(
const double& number)
703template<>
inline Line&
704Line::operator<< <long double>(
const long double& number)
776 std::istringstream input(block);
788 name(
const std::string& newName)
808 if (block_def !=
end()) (*block_def)[1] = newName;
826 std::string line_str;
829 std::size_t def_count = 0;
832 while (std::getline(is, line_str))
841 is.seekg(-
static_cast<std::ptrdiff_t
>(line_str.length() + 1), std::ios_base::cur);
868 str(
const std::string& block)
870 std::istringstream input(block);
880 std::ostringstream output;
900 if (line !=
end())
return *line;
932 {
return (*
this)[
key_type(1, key)]; }
962 if (line !=
end())
return *line;
964 throw std::out_of_range(
965 "SLHAea::Block::at(‘" + boost::join(key,
",") +
"’)");
982 if (line !=
end())
return *line;
984 throw std::out_of_range(
985 "SLHAea::Block::at(‘" + boost::join(key,
",") +
"’)");
999 at(
const std::vector<int>& key)
1013 at(
const std::vector<int>& key)
const
1029 at(
const std::string& s0,
const std::string& s1 =
"",
1030 const std::string& s2 =
"",
const std::string& s3 =
"",
1031 const std::string& s4 =
"")
1047 at(
const std::string& s0,
const std::string& s1 =
"",
1048 const std::string& s2 =
"",
const std::string& s3 =
"",
1049 const std::string& s4 =
"")
const
1123 {
return impl_.begin(); }
1132 {
return impl_.begin(); }
1141 {
return impl_.begin(); }
1150 {
return impl_.end(); }
1159 {
return impl_.end(); }
1168 {
return impl_.end(); }
1177 {
return impl_.rbegin(); }
1186 {
return impl_.rbegin(); }
1195 {
return impl_.rbegin(); }
1204 {
return impl_.rend(); }
1213 {
return impl_.rend(); }
1222 {
return impl_.rend(); }
1270 template<
class InputIterator>
static InputIterator
1272 {
return std::find_if(first, last,
key_matches(key)); }
1282 return std::find_if(
begin(),
end(),
1294 return std::find_if(
begin(),
end(),
1312 {
return impl_.size(); }
1318 return std::count_if(
begin(),
end(),
1325 {
return impl_.max_size(); }
1330 {
return impl_.empty(); }
1342 {
impl_.push_back(line); }
1362 {
impl_.pop_back(); }
1375 {
return impl_.insert(position, line); }
1387 template<
class InputIterator>
void
1389 {
impl_.insert(position, first, last); }
1401 {
return impl_.erase(position); }
1416 {
return impl_.erase(first, last); }
1433 return (line !=
end()) ?
erase(line) : line;
1451 return (line !=
rend()) ?
erase((++line).base()) :
end();
1478 return erased_count;
1536 return (
key_.empty() ||
key_.size() > line.
size()) ? false :
1547 {
return (key_part ==
"(any)") || boost::iequals(key_part, field); }
1554 template<
class Container>
static key_type
1558 key.reserve(cont.size());
1559 std::string (*
to_string)(
const typename Container::value_type&) =
1560 boost::lexical_cast<std::string, typename Container::value_type>;
1561 std::transform(cont.begin(), cont.end(), std::back_inserter(key),
1568 const std::string& s2,
const std::string& s3,
1569 const std::string& s4)
1573 if (s0.empty()) {
return key; } key.push_back(s0);
1574 if (s1.empty()) {
return key; } key.push_back(s1);
1575 if (s2.empty()) {
return key; } key.push_back(s2);
1576 if (s3.empty()) {
return key; } key.push_back(s3);
1577 if (s4.empty()) {
return key; } key.push_back(s4);
1655 std::istringstream input(coll);
1671 std::string line_str;
1677 while (std::getline(is, line_str))
1698 std::istringstream input(coll);
1708 std::ostringstream output;
1710 return output.str();
1747 throw std::out_of_range(
"SLHAea::Coll::at(‘" + blockName +
"’)");
1763 throw std::out_of_range(
"SLHAea::Coll::at(‘" + blockName +
"’)");
1785 throw std::out_of_range(
1786 "SLHAea::Coll::at(‘" + boost::join(key,
",") +
"’)");
1808 throw std::out_of_range(
1809 "SLHAea::Coll::at(‘" + boost::join(key,
",") +
"’)");
1911 {
return impl_.begin(); }
1920 {
return impl_.begin(); }
1929 {
return impl_.begin(); }
1938 {
return impl_.end(); }
1947 {
return impl_.end(); }
1956 {
return impl_.end(); }
1964 {
return impl_.rbegin(); }
1973 {
return impl_.rbegin(); }
1982 {
return impl_.rbegin(); }
1991 {
return impl_.rend(); }
2000 {
return impl_.rend(); }
2009 {
return impl_.rend(); }
2055 template<
class InputIterator>
static InputIterator
2057 {
return std::find_if(first, last,
key_matches(blockName)); }
2108 template<
class InputIterator>
static InputIterator
2109 find(InputIterator first, InputIterator last,
2127 {
return impl_.size(); }
2132 {
return impl_.max_size(); }
2137 {
return impl_.empty(); }
2200 {
impl_.pop_back(); }
2225 template<
class InputIterator>
void
2227 {
impl_.insert(position, first, last); }
2239 {
return impl_.erase(position); }
2254 {
return impl_.erase(first, last); }
2310 return erased_count;
2365 {
name_ = blockName; }
2460 Key(
const std::string& keyString)
2477 str(
const std::string& keyString)
2479 std::vector<std::string> keys;
2480 boost::split(keys, keyString, boost::is_any_of(
";"));
2482 if (keys.size() != 3)
2483 {
throw std::invalid_argument(
"SLHAea::Key::str(‘" + keyString +
"’)"); }
2487 boost::split(
line, keys[1], boost::is_any_of(
","));
2488 field = to<Line::size_type>(keys[2]);
2500 std::ostringstream output;
2501 output <<
block <<
";" << boost::join(
line,
",") <<
";" <<
field;
2502 return output.str();
2509{
return at(key.block); }
2513{
return at(key.block); }
2517{
return block(key).
at(key.line); }
2521{
return block(key).
at(key.line); }
2525{
return line(key).
at(key.field); }
2529{
return line(key).
at(key.field); }
2549{
return os << line.
str(); }
2554 std::copy(block.
begin(), block.
end(),
2555 std::ostream_iterator<Block::value_type>(os,
"\n"));
2562 std::copy(coll.
begin(), coll.
end(),
2563 std::ostream_iterator<Coll::value_type>(os));
2569{
return os << key.str(); }
2585 return (a_is_block_def != b.
is_block_def()) ? a_is_block_def :
2591{
return !(a == b); }
2623{
return !(a == b); }
2646 return std::lexicographical_compare(a.
begin(), a.
end(),
2652{
return !(a == b); }
void push_back(const value_type &line)
Adds a Line to the end of the Block.
iterator erase_first(const key_type &key)
Erases first Line that matches the provided key.
void insert(iterator position, InputIterator first, InputIterator last)
Inserts a range into the Block.
size_type erase(const key_type &key)
Erases all Lines that match the provided key.
iterator find(const key_type &key)
Tries to locate a Line in the Block.
reference at(int i0, int i1=no_index_, int i2=no_index_, int i3=no_index_, int i4=no_index_)
Locates a Line in the Block.
reference at(const std::vector< int > &key)
Locates a Line in the Block.
impl_type::pointer pointer
void uncomment()
Uncomments all Lines in the Block.
const_reference at(const key_type &key) const
Locates a Line in the Block.
void push_back(const std::string &line)
Adds a Line to the end of the Block.
void rename(const std::string &newName)
Changes the name and definition of the Block.
static key_type cont_to_key(const Container &cont)
void swap(Block &block)
Swaps data with another Block.
const_iterator find(const key_type &key) const
Tries to locate a Line in the Block.
const_reverse_iterator crend() const
const_iterator begin() const
const_iterator find_block_def() const
const_reference front() const
static key_type ints_to_key(int i0, int i1, int i2, int i3, int i4)
static Block from_str(const std::string &block)
Constructs a Block with content from a string.
const_reference at(const std::vector< int > &key) const
Locates a Line in the Block.
iterator erase(iterator position)
Erases element at given position.
iterator erase_last(const key_type &key)
Erases last Line that matches the provided key.
static const int no_index_
size_type max_size() const
const_reference at(int i0, int i1=no_index_, int i2=no_index_, int i3=no_index_, int i4=no_index_) const
Locates a Line in the Block.
size_type data_size() const
iterator find_block_def()
Block(const std::string &name="")
Constructs an empty Block.
void comment()
Comments all Lines in the Block.
size_type count(const key_type &key) const
Counts all Lines that match a given key.
iterator insert(iterator position, const value_type &line)
Inserts a Line before given position.
const_reverse_iterator rend() const
static InputIterator find(InputIterator first, InputIterator last, const key_type &key)
Tries to locate a Line in a range.
reference operator[](int key)
Locates a Line in the Block.
std::vector< std::string > key_type
impl_type::size_type size_type
impl_type::const_iterator const_iterator
impl_type::iterator iterator
impl_type::const_reverse_iterator const_reverse_iterator
const_iterator cend() const
const_iterator end() const
reference at(const std::string &s0, const std::string &s1="", const std::string &s2="", const std::string &s3="", const std::string &s4="")
Locates a Line in the Block.
iterator erase(iterator first, iterator last)
Erases a range of elements.
reference operator[](const std::vector< int > &key)
Locates a Line in the Block.
const_iterator cbegin() const
static key_type strings_to_key(const std::string &s0, const std::string &s1, const std::string &s2, const std::string &s3, const std::string &s4)
const Line & const_reference
Block & str(const std::string &block)
Assigns content from a string to the Block.
const_reference back() const
impl_type::const_pointer const_pointer
void name(const std::string &newName)
Sets the name of the Block.
impl_type::difference_type difference_type
impl_type::reverse_iterator reverse_iterator
const_reverse_iterator rbegin() const
std::vector< Line > impl_type
reverse_iterator rbegin()
Block & read(std::istream &is)
Assigns content from an input stream to the Block.
reference operator[](const std::string &key)
Locates a Line in the Block.
reference at(const key_type &key)
Locates a Line in the Block.
Block(std::istream &is)
Constructs a Block with content from an input stream.
const_reverse_iterator crbegin() const
const std::string & name() const
const_reference at(const std::string &s0, const std::string &s1="", const std::string &s2="", const std::string &s3="", const std::string &s4="") const
Locates a Line in the Block.
void reformat()
Reformats all Lines in the Block.
reference operator[](const key_type &key)
Locates a Line in the Block.
iterator erase_first(const key_type &blockName)
Erases first Block with a given name.
std::deque< Block > impl_type
const_iterator find(const value_type::key_type &key) const
Tries to locate a Block in the Coll.
impl_type::size_type size_type
const_reference front() const
void swap(Coll &coll)
Swaps data with another Coll.
void uncomment()
Uncomments all Blocks in the Coll.
void push_front(const std::string &blockString)
Adds a Block to the begin of the Coll.
impl_type::difference_type difference_type
reference block(const Key &key)
Accesses a Block in the Coll.
const_reference back() const
impl_type::const_reverse_iterator const_reverse_iterator
const_iterator cbegin() const
const_iterator end() const
const_reference at(const key_type &blockName) const
Locates a Block in the Coll.
impl_type::const_iterator const_iterator
void push_front(const value_type &block)
Adds a Block to the begin of the Coll.
const_reverse_iterator rbegin() const
iterator erase_last(const key_type &blockName)
Erases last Block with a given name.
Coll & str(const std::string &coll)
Assigns content from a string to the Coll.
impl_type::pointer pointer
void reformat()
Reformats all Blocks in the Coll.
iterator find(const key_type &blockName)
Tries to locate a Block in the Coll.
void push_back(const std::string &blockString)
Adds a Block to the end of the Coll.
const_reverse_iterator rend() const
Coll(std::istream &is)
Constructs a Coll with content from an input stream.
iterator find(const value_type::key_type &key)
Tries to locate a Block in the Coll.
const_reverse_iterator crbegin() const
const_reverse_iterator crend() const
size_type erase(const key_type &blockName)
Erases all Blocks with a given name.
impl_type::const_pointer const_pointer
reference at(const key_type &blockName)
Locates a Block in the Coll.
Coll & read(std::istream &is)
Assigns content from an input stream to the Coll.
void push_back(const value_type &block)
Adds a Block to the end of the Coll.
impl_type::reverse_iterator reverse_iterator
impl_type::iterator iterator
size_type count(const key_type &blockName) const
Counts all Blocks with a given name.
pointer push_back_named_block(const key_type &blockName)
void comment()
Comments all Blocks in the Coll.
iterator erase(iterator first, iterator last)
Erases a range of elements.
const_iterator find(const key_type &blockName) const
Tries to locate a Block in the Coll.
iterator insert(iterator position, const value_type &block)
Inserts a Block before given position.
void insert(iterator position, InputIterator first, InputIterator last)
Inserts a range into the Coll.
reverse_iterator rbegin()
iterator erase_if_empty(const key_type &blockName, const size_type &offset=0)
reference operator[](const key_type &blockName)
Locates a Block in the Coll.
Block::reference line(const Key &key)
Accesses a single Line in the Coll.
const_iterator cend() const
static Coll from_str(const std::string &coll)
Constructs a Coll with content from a string.
const_reference at(const value_type::key_type &key) const
Locates a Block in the Coll.
static InputIterator find(InputIterator first, InputIterator last, const key_type &blockName)
Tries to locate a Block in a range.
size_type max_size() const
const Block & const_reference
reference at(const value_type::key_type &key)
Locates a Block in the Coll.
iterator erase(iterator position)
Erases element at given position.
static InputIterator find(InputIterator first, InputIterator last, const value_type::key_type &key)
Tries to locate a Block in a range.
Line::reference field(const Key &key)
Accesses a single field in the Coll.
const_iterator begin() const
reverse_iterator rbegin()
impl_type::const_reverse_iterator const_reverse_iterator
size_type data_size() const
impl_type::pointer pointer
Line & insert_fundamental_type(const T &arg)
bool is_data_line() const
Line & append(const std::string &arg)
Appends a string to the end of the Line.
static bool is_comment(const value_type &field)
const_reverse_iterator rend() const
reference operator[](size_type n)
Subscript access to the strings contained in the Line.
const_iterator begin() const
impl_type::difference_type difference_type
const_iterator cbegin() const
const_reference front() const
size_type max_size() const
const_reverse_iterator crend() const
std::vector< std::string > impl_type
impl_type::reverse_iterator reverse_iterator
Line(const std::string &line)
Constructs a Line from a string.
reference at(size_type n)
Provides access to the strings contained in the Line.
const_reference at(size_type n) const
Provides access to the strings contained in the Line.
std::vector< std::size_t > columns_
static const std::size_t min_width_
static bool is_block_specifier(const value_type &field)
impl_type::const_pointer const_pointer
const_iterator end() const
bool contains_comment() const
static std::size_t calc_spaces_for_indent(const std::size_t &pos)
Line & operator+=(const std::string &arg)
Appends a string to the end of the Line.
Line & operator<<(const T &field)
Inserts an element at the end of the Line.
static bool starts_with_sign(const value_type &field)
impl_type::iterator iterator
bool is_block_def() const
const_iterator cend() const
Line & operator=(const std::string &line)
Assigns content from a string to the Line.
const std::string & const_reference
Line & str(const std::string &line)
Assigns content to the Line based on a string.
bool is_comment_line() const
void swap(Line &line)
Swaps data with another Line.
impl_type::size_type size_type
static const std::size_t shift_width_
const_reference back() const
const_reverse_iterator rbegin() const
const_reverse_iterator crbegin() const
const_reference operator[](size_type n) const
Subscript access to the strings contained in the Line.
impl_type::const_iterator const_iterator
void trim_right(std::string &str)
std::string to_upper_copy(const std::string &str)
void trim_left(std::string &str)
bool is_all_whitespace(const std::string &str)
std::istream & operator>>(std::istream &is, Block &block)
bool operator==(const Line &a, const Line &b)
bool operator!=(const Line &a, const Line &b)
bool operator<(const Line &a, const Line &b)
bool operator>(const Line &a, const Line &b)
std::ostream & operator<<(std::ostream &os, const Line &line)
bool operator<=(const Line &a, const Line &b)
std::string to_string(const Source &arg)
Converts an object of type Source to a string.
Target to(const Source &arg)
Converts an object of type Source to an object of type Target.
bool operator>=(const Line &a, const Line &b)
bool operator()(const value_type &line) const
static bool parts_equal(const std::string &key_part, const std::string &field)
key_matches(const key_type &key)
void set_key(const key_type &key)
key_matches_block_def(const value_type::key_type &key)
bool operator()(const value_type &block) const
value_type::key_matches key_matches_
void set_key(const value_type::key_type &key)
void set_key(const key_type &blockName)
key_matches(const key_type &blockName)
bool operator()(const value_type &block) const
Key(const Coll::key_type &_block, const Block::key_type &_line, const Line::size_type &_field)
Constructs a Key from explicit key values.
std::string str() const
Converts a Key into its string representation.
Key(const std::string &keyString)
Constructs a Key from a string.
Key & str(const std::string &keyString)
Converts a string to a Key.
Key(const char *keyString)
Constructs a Key from a string.