28 #ifndef CONFIG_HPP_INCLUDED
29 #define CONFIG_HPP_INCLUDED
42 #include <boost/exception/exception.hpp>
43 #include <boost/variant/apply_visitor.hpp>
44 #include <boost/variant/variant.hpp>
46 #include <boost/utility/enable_if.hpp>
47 #include <boost/type_traits/is_same.hpp>
48 #include <boost/type_traits/add_const.hpp>
49 #include <boost/type_traits/is_base_of.hpp>
56 # ifdef __clang__ // Check this first, because clang also defines __GNUC__
57 # ifdef __apple_build_version__ // Apple clang
58 # if (__clang_major__ == 5 && __clang_minor__ >= 1) || __clang_major__ > 5 // Apple clang 5.1+
59 # define USE_HETEROGENOUS_LOOKUPS
61 # else // Non-Apple clang
62 # if (__clang_major__ == 3 && __clang_minor__ >= 4) || __clang_major__ > 3 // clang 3.4+
63 # define USE_HETEROGENOUS_LOOKUPS
66 # elif defined(__GNUC__) && __GNUC__ >= 5 // GCC 5.0+
67 # define USE_HETEROGENOUS_LOOKUPS
71 #if defined(_MSC_VER) && _MSC_VER >= 1900 // MSVC 2015
72 # define USE_HETEROGENOUS_LOOKUPS
120 explicit operator bool()
const
125 #ifdef USE_HETEROGENOUS_LOOKUPS
154 friend bool operator<(
const this_type& a,
const this_type& b) {
return a.
i_ < b.
i_; }
155 friend bool operator<=(
const this_type& a,
const this_type& b) {
return a.
i_ <= b.
i_; }
156 friend bool operator>=(
const this_type& a,
const this_type& b) {
return a.
i_ >= b.
i_; }
157 friend bool operator>(
const this_type& a,
const this_type& b) {
return a.
i_ > b.
i_; }
163 friend Itor::difference_type
operator-(
const this_type& a,
const this_type& b) {
return a.
i_ - b.
i_; }
179 typedef child_list::const_iterator
Itor;
195 friend bool operator<(
const this_type& a,
const this_type& b) {
return a.
i_ < b.
i_; }
196 friend bool operator<=(
const this_type& a,
const this_type& b) {
return a.
i_ <= b.
i_; }
197 friend bool operator>=(
const this_type& a,
const this_type& b) {
return a.
i_ >= b.
i_; }
198 friend bool operator>(
const this_type& a,
const this_type& b) {
return a.
i_ > b.
i_; }
204 friend Itor::difference_type
operator-(
const this_type& a,
const this_type& b) {
return a.
i_ - b.
i_; }
235 const std::string &
str()
const
239 friend std::ostream&
operator<<(std::ostream &os,
const true_false &
v);
250 const std::string &
str()
const
254 friend std::ostream&
operator<<(std::ostream &os,
const yes_no &
v);
257 class equality_visitor;
268 typedef boost::variant<boost::blank,
270 int,
unsigned long long, double,
309 bool to_bool(
bool def =
false)
const;
310 int to_int(
int def = 0)
const;
316 std::string
str()
const;
324 typename boost::enable_if<boost::is_base_of<enum_tag, T>, T>
::type to_enum(
const T &
v)
const
326 return T::string_to_enum(this->
str(), v);
345 bool equals(
const std::string&
str)
const;
351 {
return val.
equals(str); }
354 typename boost::enable_if<boost::is_same<const char*, T>,
bool>
::type
356 {
return val.
equals(std::string(str)); }
360 {
return val ==
str; }
364 {
return !(val ==
str); }
368 {
return !(val ==
str); }
376 template <
typename V>
378 {
return boost::apply_visitor(visitor, value_); }
389 #ifdef USE_HETEROGENOUS_LOOKUPS
402 typedef attribute_map::const_iterator
Itor;
421 const_child_itors
child_range(
const std::string& key)
const;
422 unsigned child_count(
const std::string &key)
const;
435 bool has_child(
const std::string& key)
const;
450 #ifdef USE_HETEROGENOUS_LOOKUPS
453 {
return child_impl(key, N - 1,
n); }
455 config &child_impl(
const char* key,
int len,
int n = 0);
467 #ifdef USE_HETEROGENOUS_LOOKUPS
469 const config &
child(
const char(&key)[N],
int n = 0)
const
470 {
return const_cast<config *
>(
this)->child_impl(key, N- 1,
n); }
486 config&
child(
const std::string& key,
const std::string& parent);
503 const std::string& key
504 ,
const std::string& parent)
const;
516 attribute_value &
operator[](
const std::string &key);
522 const attribute_value &
operator[](
const std::string &key)
const;
524 #ifdef USE_HETEROGENOUS_LOOKUPS
530 inline const attribute_value &
operator[](
const char (&key)[N])
const
533 return get_attribute(key, N - 1);
537 inline attribute_value&
operator[](
const char (&key)[N])
546 const attribute_value *
get(
const std::string &key)
const;
553 const attribute_value &
get_old_attribute(
const std::string &key,
const std::string &old_key,
const std::string&
msg =
"")
const;
566 bool has_old_attribute(
const std::string &key,
const std::string &old_key,
const std::string&
msg =
"")
const;
570 template<
typename... T>
572 for(
const std::string& key : {keys...}) {
584 const std::string &
value);
587 const std::string &
value)
const
591 template<
typename... T>
593 for(std::string key : {keys...}) {
609 std::string
debug()
const;
610 std::string
hash()
const;
628 const child_map::key_type &
key;
647 typedef std::vector<child_pos>::const_iterator
Itor;
759 #ifdef USE_HETEROGENOUS_LOOKUPS
760 const attribute_value& get_attribute(
const char* key,
int len)
const;
const attribute_value & get_old_attribute(const std::string &key, const std::string &old_key, const std::string &msg="") const
Function to handle backward compatibility Get the value of key and if missing try old_key and log msg...
friend this_type operator+(const this_type &a, Itor::difference_type n)
friend this_type operator-(const this_type &a, Itor::difference_type n)
child_itors child_range(const std::string &key)
attribute_value & operator=(unsigned v)
double to_double(double def=0.) const
void remove_attribute(const std::string &key)
bool friend operator!=(const attribute_value &val, const T &str)
~attribute_value()
Default implementation, but defined out-of-line for efficiency reasons.
const_child_iterator & operator--()
error(const std::string &message)
static const std::string s_no
bool matches(const config &filter) const
static const std::string s_false
void append_attributes(const config &cfg)
Adds attributes from cfg.
boost::enable_if< boost::is_base_of< enum_tag, T >, T >::type to_enum(const T &v) const
const std::string & str() const
friend bool operator<=(const this_type &a, const this_type &b)
friend bool operator>(const this_type &a, const this_type &b)
all_children_iterator ordered_end() const
std::pair< const_attribute_iterator, const_attribute_iterator > const_attr_itors
bool operator==(const config &, const config &)
const_child_iterator(const Itor &i)
size_t to_size_t(size_t def=0) const
void append(const config &cfg)
Append data from another config object to this one.
config & operator[](Itor::difference_type n) const
bool operator!=(const const_child_iterator &i) const
const config * operator->() const
friend Itor::difference_type operator-(const this_type &a, const this_type &b)
unsigned attribute_count() const
Note: this function also counts the 'blank' attributes, so it might return more than one might expect...
std::vector< child_pos >::const_iterator Itor
bool operator!=(const child_iterator &i) const
bool to_bool(bool def=false) const
GLuint GLuint GLsizei GLenum type
void merge_children(const std::string &key)
All children with the given key will be merged into the first element with that key.
bool operator==(const const_child_iterator &i) const
friend bool operator>(const this_type &a, const this_type &b)
config & child_or_add(const std::string &key)
Returns a reference to the first child with the given key.
friend bool operator<=(const this_type &a, const this_type &b)
bool operator==(const const_attribute_iterator &i) const
friend bool operator==(const config &a, const config &b)
Visitor for converting a variant to a string.
friend this_type operator+(const this_type &a, Itor::difference_type n)
attribute_map::value_type attribute
const config & child(const std::string &key, int n=0) const
Returns the nth child with the given key, or a reference to an invalid config if there is none...
child_iterator(const Itor &i)
const_child_iterator operator++(int)
child_list::iterator Itor
const any_child * operator->() const
bool operator==(const child_pos &o) const
GLuint const GLfloat * val
value_type value_
The stored value will always use the first type from the variant definition that can represent it and...
reference operator*() const
friend this_type operator+(Itor::difference_type n, const this_type &a)
V::result_type apply_visitor(const V &visitor) const
Applies a visitor to the underlying variant.
attribute_map::const_iterator Itor
void append_children(const config &cfg)
Adds children from cfg.
const config & child_or_empty(const std::string &key) const
Returns the first child with the given key, or an empty config if there is none.
bool operator!=(const config &a, const config &b)
void clear_diff_track(const config &diff)
Clear any tracking info from a previous apply_diff call with tracking.
std::string debug() const
void clear_children(const std::string &key)
bool empty() const
Tests for an attribute that either was never set or was set to "".
friend std::ostream & operator<<(std::ostream &os, const true_false &v)
std::pair< const_child_iterator, const_child_iterator > const_child_itors
const_attribute_iterator & operator++()
Variant for storing WML attributes.
GLboolean GLenum GLenum GLvoid * values
const_attribute_iterator(const Itor &i)
bool operator==(const child_iterator &i) const
bool blank() const
Tests for an attribute that was never set.
boost::variant< boost::blank, true_false, yes_no, int, unsigned long long, double, std::string, t_string > value_type
friend bool operator>=(const this_type &a, const this_type &b)
GLdouble GLdouble GLdouble b
static bool valid_id(const std::string &id)
void merge_with(const config &c)
Merge config 'c' into this config, overwriting this config's values.
void inherit_from(const config &c)
Merge config 'c' into this config, preserving this config's values.
child_list::const_iterator Itor
this_type & operator-=(Itor::difference_type n)
bool has_child(const std::string &key) const
Determine whether a config has a child or not.
bool operator!=(const attribute_value &other) const
all_children_iterator(const Itor &i)
const_child_iterator(const child_iterator &i)
child_iterator & operator++()
void splice_children(config &src, const std::string &key)
Moves all the children with tag key from src to this.
void check_valid() const
Raises an exception if this is not valid.
boost::enable_if< boost::is_base_of< enum_tag, T >, attribute_value & >::type operator=(const T &v)
this_type & operator+=(Itor::difference_type n)
static const std::string s_yes
void clear_children(T...keys)
child_iterator & operator--()
const_child_iterator this_type
GLsizei const GLfloat * value
all_children_itors all_children_range() const
In-order iteration over all children.
const child_map::key_type & key
attribute_value & operator=(const char *v)
GLboolean GLboolean GLboolean GLboolean a
void remove_child(const std::string &key, unsigned index)
this_type & operator-=(Itor::difference_type n)
bool friend operator!=(const T &str, const attribute_value &val)
const_child_iterator & operator++()
std::pair< all_children_iterator, all_children_iterator > all_children_itors
config & add_child(const std::string &key)
std::forward_iterator_tag iterator_category
std::vector< child_pos > ordered_children
A wrapper for bool to get the correct streaming ("yes"/"no").
attribute_map values
All the attributes of this node.
const config & operator*() const
friend Itor::difference_type operator-(const this_type &a, const this_type &b)
const attribute & operator*() const
const_attribute_iterator operator++(int)
void apply_diff(const config &diff, bool track=false)
A function to apply a diff config onto this config object.
const attribute * operator->() const
bool operator==(const all_children_iterator &i) const
const any_child reference
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
bool friend operator==(const T &str, const attribute_value &val)
all_children_iterator erase(const all_children_iterator &i)
all_children_iterator operator++(int)
const arrow_helper pointer
config get_diff(const config &c) const
A function to get the differences between this object, and 'c', as another config object...
bool operator!=(const child_pos &o) const
attribute_value()
Default implementation, but defined out-of-line for efficiency reasons.
this_type & operator+=(Itor::difference_type n)
boost::enable_if< boost::is_same< const std::string, typename boost::add_const< T >::type >, bool >::type friend operator==(const attribute_value &val, const T &str)
std::forward_iterator_tag iterator_category
config & operator*() const
child_iterator operator--(int)
true_false(bool value=false)
boost::enable_if< boost::is_same< const char *, T >, bool >::type friend operator==(const attribute_value &val, T str)
const_attr_itors attribute_range() const
child_map children
A list of all children of this node.
bool operator!=(const all_children_iterator &i) const
attribute_value & operator[](const std::string &key)
Returns a reference to the attribute with the given key.
std::pair< child_iterator, child_iterator > child_itors
const attribute & reference
child_pos(child_map::iterator p, unsigned i)
friend this_type operator-(const this_type &a, Itor::difference_type n)
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
std::map< std::string, child_list > child_map
pointer operator->() const
config * operator->() const
unsigned child_count(const std::string &key) const
void merge_attributes(const config &)
GLuint const GLchar * name
attribute_value & operator=(const attribute_value &)
Default implementation, but defined out-of-line for efficiency reasons.
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
static const char * diff_track_attribute
The name of the attribute used for tracking diff changes.
virtual config::attribute_value get_variable_const(const std::string &id) const =0
bool equals(const std::string &str) const
Checks for equality of the attribute values when viewed as strings.
arrow_helper(const all_children_iterator &i)
bool has_attribute(const std::string &key) const
long long to_long_long(long long def=0) const
Base class for all the errors encountered by the engine.
config & child(const std::string &key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
friend bool operator<(const this_type &a, const this_type &b)
bool operator!=(const const_attribute_iterator &i) const
unsigned all_children_count() const
config & find_child(const std::string &key, const std::string &name, const std::string &value)
Returns the first child of tag key with a name attribute containing value.
void recursive_clear_value(const std::string &key)
time_t to_time_t(time_t def=0) const
GLsizei GLenum GLuint GLuint GLsizei char * message
int to_int(int def=0) const
std::vector< config * > child_list
std::random_access_iterator_tag iterator_category
const_child_iterator operator--(int)
friend bool operator>=(const this_type &a, const this_type &b)
const config & operator[](Itor::difference_type n) const
const attribute * pointer
const config & find_child(const std::string &key, const std::string &name, const std::string &value) const
unsigned to_unsigned(unsigned def=0) const
any_child(const child_map::key_type *k, const config *c)
bool operator==(const attribute_value &other) const
Checks for equality of the attribute values when viewed as strings.
child_iterator operator++(int)
void remove_attributes(T...keys)
std::random_access_iterator_tag iterator_category
std::map< std::string, attribute_value > attribute_map
A config object defines a single node in a WML file, with access to child nodes.
attribute_value & operator=(unsigned long v)
std::ostream & operator<<(std::ostream &, const config &)
config & operator=(const config &)
static const std::string s_true
friend bool operator<(const this_type &a, const this_type &b)
GLsizei const GLcharARB ** string
bool has_old_attribute(const std::string &key, const std::string &old_key, const std::string &msg="") const
Function to handle backward compatibility Check if has key or old_key and log msg as a WML error (if ...
config & add_child_at(const std::string &key, const config &val, unsigned index)
attribute_value & operator=(long v)
A wrapper for bool to get the correct streaming ("true"/"false").
void merge_children_by_attribute(const std::string &key, const std::string &attribute)
All children with the given key and with equal values of the specified attribute will be merged into ...
all_children_iterator ordered_begin() const
all_children_iterator & operator++()
friend this_type operator+(Itor::difference_type n, const this_type &a)
const std::string & str() const