The Battle for Wesnoth  1.19.8+dev
config.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2024
3  by David White <dave@whitevine.net>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 /**
17  * @file
18  * Definitions for the interface to Wesnoth Markup Language (WML).
19  *
20  * This module defines the interface to Wesnoth Markup Language (WML). WML is
21  * a simple hierarchical text-based file format. The format is defined in
22  * Wiki, under BuildingScenariosWML
23  *
24  * All configuration files are stored in this format, and data is sent across
25  * the network in this format. It is thus used extensively throughout the
26  * game.
27  */
28 
29 #pragma once
30 
32 #include "exceptions.hpp"
33 #include "utils/const_clone.hpp"
35 #include "utils/ranges.hpp"
36 
37 #include <functional>
38 #include <iosfwd>
39 #include <map>
40 #include <memory>
41 #include <string>
42 #include <string_view>
43 #include <utility>
44 #include <vector>
45 
46 #include <boost/range/iterator_range.hpp>
47 
48 using config_key_type = std::string_view;
49 enum class DEP_LEVEL : uint8_t;
50 
51 class config;
52 
53 template<class T>
55 {
56 public:
57  optional_config_impl() = default;
58 
60  : opt_(&ref)
61  {
62  }
63 
64  optional_config_impl(utils::nullopt_t)
65  : opt_()
66  {
67  }
68 
69  T& value() const
70  {
71  if(opt_) {
72  return *opt_;
73  } else {
74  // We're going to drop this codepath once we can use optional::value anyway, but just
75  // noting we want this function to ultimately throw utils::bad_optional_access.
76  throw std::runtime_error("Optional reference has no value");
77  }
78  }
79 
81  {
82  opt_ = &new_ref;
83  return *this;
84  }
85 
86  bool has_value() const
87  {
88 #ifdef DEBUG_CONFIG
89  tested_ = true;
90 #endif
91  return opt_ != nullptr;
92 
93  }
94 
95  explicit operator bool() const
96  {
97  return has_value();
98  }
99 
101  {
103  }
104 
105  /** Returns a pointer to the referenced object or nullptr if no reference is held. */
106  T* ptr() const
107  {
108  if(opt_) {
109  return &value();
110  } else {
111  return nullptr;
112  }
113  }
114 
115  T* operator->() const
116  {
117  assert(tested());
118  return &value();
119  }
120 
121  T& operator*() const
122  {
123  assert(tested());
124  return value();
125  }
126 
128  {
129  assert(tested());
130  return value()[key];
131  }
132 
134  {
136  }
137  bool tested() const
138  {
139 #ifdef DEBUG_CONFIG
140  return tested_;
141 #else
142  return true;
143 #endif
144  }
145 private:
146  T* opt_;
147 #ifdef DEBUG_CONFIG
148  mutable bool tested_;
149 #endif
150 };
151 
152 bool operator==(const config &, const config &);
153 inline bool operator!=(const config &a, const config &b) { return !operator==(a, b); }
154 std::ostream &operator << (std::ostream &, const config &);
155 
156 /** A config object defines a single node in a WML file, with access to child nodes. */
157 class config
158 {
159  friend bool operator==(const config& a, const config& b);
160 public:
161  // Create an empty node.
162  config();
163 
164  config(const config &);
165  config &operator=(const config &);
166 
167  config(config &&);
168  config &operator=(config &&);
169 
170  /**
171  * Creates a config object with an empty child of name @a child.
172  */
173  explicit config(config_key_type child);
174 
175  /**
176  * Creates a config with several attributes and children.
177  * Pass the keys/tags and values/children alternately.
178  * For example: config("key", 42, "value", config())
179  */
180  template<typename... Args>
181  explicit config(config_key_type first, Args&&... args);
182 
183  ~config();
184 
185  // Verifies that the string can be used as a tag name
186  static bool valid_tag(config_key_type name);
187 
188  // Verifies that the string can be used as an attribute name
189  static bool valid_attribute(config_key_type name);
190 
191  typedef std::vector<std::unique_ptr<config>> child_list;
192  typedef std::map<std::string, child_list, std::less<>> child_map;
193 
194  struct const_child_iterator;
195 
197  {
199  typedef std::random_access_iterator_tag iterator_category;
200  typedef config *pointer;
201  typedef config &reference;
203  typedef Itor::difference_type difference_type;
205  explicit child_iterator(const Itor &i): i_(i) {}
206 
207  child_iterator &operator++() { ++i_; return *this; }
209  child_iterator &operator--() { --i_; return *this; }
211 
212  reference operator*() const { return **i_; }
213  pointer operator->() const { return &**i_; }
214 
215  bool operator==(const child_iterator &i) const { return i_ == i.i_; }
216  bool operator!=(const child_iterator &i) const { return i_ != i.i_; }
217  bool operator==(const const_child_iterator &i) const { return i == *this; }
218  bool operator!=(const const_child_iterator &i) const { return i != *this; }
219 
220  friend bool operator<(const this_type& a, const this_type& b) { return a.i_ < b.i_; }
221  friend bool operator<=(const this_type& a, const this_type& b) { return a.i_ <= b.i_; }
222  friend bool operator>=(const this_type& a, const this_type& b) { return a.i_ >= b.i_; }
223  friend bool operator>(const this_type& a, const this_type& b) { return a.i_ > b.i_; }
224 
225  this_type& operator+=(Itor::difference_type n) { i_ += n; return *this; }
226  this_type& operator-=(Itor::difference_type n) { i_ -= n; return *this; }
227 
228  config &operator[](Itor::difference_type n) const { return *i_[n]; }
229  friend Itor::difference_type operator-(const this_type& a, const this_type& b) { return a.i_ - b.i_; }
230  friend this_type operator-(const this_type& a, Itor::difference_type n) { return this_type(a.i_ - n); }
231  friend this_type operator+(const this_type& a, Itor::difference_type n) { return this_type(a.i_ + n); }
232  friend this_type operator+(Itor::difference_type n, const this_type& a) { return this_type(a.i_ + n); }
233  private:
235  friend struct const_child_iterator;
236  };
237 
239  {
240  typedef const config value_type;
241  typedef std::random_access_iterator_tag iterator_category;
242  typedef const config *pointer;
243  typedef const config &reference;
244  typedef child_list::const_iterator Itor;
245  typedef Itor::difference_type difference_type;
247  explicit const_child_iterator(const Itor &i): i_(i) {}
249 
250  const_child_iterator &operator++() { ++i_; return *this; }
252  const_child_iterator &operator--() { --i_; return *this; }
254 
255  reference operator*() const { return **i_; }
256  pointer operator->() const { return &**i_; }
257 
258  bool operator==(const const_child_iterator &i) const { return i_ == i.i_; }
259  bool operator!=(const const_child_iterator &i) const { return i_ != i.i_; }
260  bool operator==(const child_iterator &i) const { return i_ == i.i_; }
261  bool operator!=(const child_iterator &i) const { return i_ != i.i_; }
262 
263  friend bool operator<(const this_type& a, const this_type& b) { return a.i_ < b.i_; }
264  friend bool operator<=(const this_type& a, const this_type& b) { return a.i_ <= b.i_; }
265  friend bool operator>=(const this_type& a, const this_type& b) { return a.i_ >= b.i_; }
266  friend bool operator>(const this_type& a, const this_type& b) { return a.i_ > b.i_; }
267 
268  this_type& operator+=(Itor::difference_type n) { i_ += n; return *this; }
269  this_type& operator-=(Itor::difference_type n) { i_ -= n; return *this; }
270 
271  const config &operator[](Itor::difference_type n) const { return *i_[n]; }
272  friend Itor::difference_type operator-(const this_type& a, const this_type& b) { return a.i_ - b.i_; }
273  friend this_type operator-(const this_type& a, Itor::difference_type n) { return this_type(a.i_ - n); }
274  friend this_type operator+(const this_type& a, Itor::difference_type n) { return this_type(a.i_ + n); }
275  friend this_type operator+(Itor::difference_type n, const this_type& a) { return this_type(a.i_ + n); }
276 
277  private:
279  };
280 
281  typedef boost::iterator_range<child_iterator> child_itors;
282  typedef boost::iterator_range<const_child_iterator> const_child_itors;
283 
284  /**
285  * Variant for storing WML attributes.
286  * The most efficient type is used when assigning a value. For instance,
287  * strings "yes", "no", "true", "false" will be detected and stored as boolean.
288  * @note The blank variant is only used when querying missing attributes.
289  * It is not stored in config objects.
290  */
292 
293  typedef std::map<
294  std::string
296  , std::less<>
298  typedef attribute_map::value_type attribute;
300 
302  {
304  typedef std::bidirectional_iterator_tag iterator_category;
305  typedef attribute *pointer;
308  typedef Itor::difference_type difference_type;
309  explicit attribute_iterator(const Itor &i): i_(i) {}
310 
311  attribute_iterator &operator++() { ++i_; return *this; }
313  attribute_iterator &operator--() { --i_; return *this; }
315 
316  reference operator*() const { return *i_; }
317  pointer operator->() const { return &*i_; }
318 
319  bool operator==(const attribute_iterator &i) const { return i_ == i.i_; }
320  bool operator!=(const attribute_iterator &i) const { return i_ != i.i_; }
321  bool operator==(const const_attribute_iterator &i) const { return i == *this; }
322  bool operator!=(const const_attribute_iterator &i) const { return i != *this; }
323 
324  private:
327  };
328 
330  {
331  typedef const attribute value_type;
332  typedef std::bidirectional_iterator_tag iterator_category;
333  typedef const attribute *pointer;
334  typedef const attribute &reference;
335  typedef attribute_map::const_iterator Itor;
336  typedef Itor::difference_type difference_type;
337  explicit const_attribute_iterator(const Itor &i): i_(i) {}
339 
340  const_attribute_iterator &operator++() { ++i_; return *this; }
342 
343  const_attribute_iterator &operator--() { --i_; return *this; }
345 
346  reference operator*() const { return *i_; }
347  pointer operator->() const { return &*i_; }
348 
349  bool operator==(const const_attribute_iterator &i) const { return i_ == i.i_; }
350  bool operator!=(const const_attribute_iterator &i) const { return i_ != i.i_; }
351  bool operator==(const attribute_iterator &i) const { return i_ == i.i_; }
352  bool operator!=(const attribute_iterator &i) const { return i_ != i.i_; }
353 
354  private:
356  };
357 
358  typedef boost::iterator_range<const_attribute_iterator> const_attr_itors;
359  typedef boost::iterator_range<attribute_iterator> attr_itors;
360 
363  std::size_t child_count(config_key_type key) const;
364  std::size_t all_children_count() const;
365  /** Count the number of non-blank attributes */
366  std::size_t attribute_count() const;
367 
368  /**
369  * Determine whether a config has a child or not.
370  *
371  * @param key The key of the child to find.
372  *
373  * @returns Whether a child is available.
374  */
375  bool has_child(config_key_type key) const;
376 
377  /**
378  * Returns the first child with the given @a key, or an empty config if there is none.
379  */
380  const config & child_or_empty(config_key_type key) const;
381 
382  /**
383  * Returns the nth child with the given @a key, or
384  * throws an error if there is none.
385  * @note A negative @a n accesses from the end of the object.
386  * For instance, -1 is the index of the last child.
387  */
388 
389  config& mandatory_child(config_key_type key, int n = 0);
390  /**
391  * Returns the nth child with the given @a key, or
392  * throws an error if there is none.
393  * @note A negative @a n accesses from the end of the object.
394  * For instance, -1 is the index of the last child.
395  */
396  const config& mandatory_child(config_key_type key, int n = 0) const;
397 
398  /** Equivalent to @ref mandatory_child, but returns an empty optional if the nth child was not found. */
400 
401  /** Equivalent to @ref mandatory_child, but returns an empty optional if the nth child was not found. */
403 
404  /**
405  * Returns a mandatory child node.
406  *
407  * If the child is not found a @ref wml_exception is thrown.
408  *
409  * @pre parent[0] == '['
410  * @pre parent[parent.size() - 1] == ']'
411  *
412  * @param key The key of the child item to return.
413  * @param parent The section in which the child should reside.
414  * This is only used for error reporting.
415  *
416  * @returns The wanted child node.
417  */
418  config& mandatory_child(config_key_type key, const std::string& parent);
419 
420  /**
421  * Returns a mandatory child node.
422  *
423  * If the child is not found a @ref wml_exception is thrown.
424  *
425  * @pre parent[0] == '['
426  * @pre parent[parent.size() - 1] == ']'
427  *
428  * @param key The key of the child item to return.
429  * @param parent The section in which the child should reside.
430  * This is only used for error reporting.
431  *
432  * @returns The wanted child node.
433  */
434  const config& mandatory_child(config_key_type key, const std::string& parent) const;
435 
436  /**
437  * Get a deprecated child and log a deprecation message
438  * @param old_key The deprecated child to return if present
439  * @param in_tag The name of the tag this child appears in
440  * @param level The deprecation level
441  * @param message An explanation of the deprecation, possibly mentioning an alternative
442  * @note The deprecation message will be a level 3 deprecation.
443  */
444  optional_config_impl<const config> get_deprecated_child(config_key_type old_key, const std::string& in_tag, DEP_LEVEL level, const std::string& message) const;
445 
446  /**
447  * Get a deprecated child range and log a deprecation message
448  * @param old_key The deprecated child to return if present
449  * @param in_tag The name of the tag this child appears in
450  * @param level The deprecation level
451  * @param message An explanation of the deprecation, possibly mentioning an alternative
452  * @note The deprecation message will be a level 3 deprecation.
453  */
454  const_child_itors get_deprecated_child_range(config_key_type old_key, const std::string& in_tag, DEP_LEVEL level, const std::string& message) const;
455 
457  config& add_child(config_key_type key, const config& val);
458  /**
459  * @param key the tag name
460  * @param val the contents of the tag
461  * @param index is the index of the new child within all children of type key.
462  */
463  config& add_child_at(config_key_type key, const config &val, std::size_t index);
464 
465  config &add_child(config_key_type key, config &&val);
466 
467  /**
468  * Returns a reference to the attribute with the given @a key.
469  * Creates it if it does not exist.
470  */
472 
473  /**
474  * Returns a reference to the attribute with the given @a key
475  * or to a dummy empty attribute if it does not exist.
476  */
477  const attribute_value& operator[](config_key_type key) const;
478 
479  /**
480  * Returns a pointer to the attribute with the given @a key
481  * or nullptr if it does not exist.
482  */
483  const attribute_value *get(config_key_type key) const;
484 
485  /**
486  * Chooses a value. If the value specified by @a key is
487  * blank, then @a default_key is chosen instead.
488  * If both values are blank or not set, then an empty value is returned.
489  */
490  const attribute_value& get_or(const config_key_type key, const config_key_type default_key) const;
491 
492  /**
493  * Function to handle backward compatibility
494  * Get the value of key and if missing try old_key
495  * and log a deprecation message
496  * @param key The non-deprecated attribute to return
497  * @param old_key The deprecated attribute to return if @a key is missing
498  * @param in_tag The name of the tag these attributes appear in
499  * @param message An explanation of the deprecation, to be output if @a old_key is present.
500  * @note The deprecation message will be a level 1 deprecation.
501  */
502  const attribute_value &get_old_attribute(config_key_type key, const std::string &old_key, const std::string& in_tag, const std::string& message = "") const;
503 
504  /**
505  * Get a deprecated attribute without a direct substitute,
506  * and log a deprecation message
507  * @param old_key The deprecated attribute to return if present
508  * @param in_tag The name of the tag this attribute appears in
509  * @param level The deprecation level
510  * @param message An explanation of the deprecation, possibly mentioning an alternative
511  */
512  const attribute_value& get_deprecated_attribute(config_key_type old_key, const std::string& in_tag, DEP_LEVEL level, const std::string& message) const;
513 
514  /**
515  * Inserts an attribute into the config
516  * @param key The name of the attribute
517  * @param value The attribute value
518  */
519  template<typename T>
520  void insert(config_key_type key, T&& value)
521  {
522  operator[](key) = std::forward<T>(value);
523  }
524 
525  /**
526  * Returns a reference to the first child with the given @a key.
527  * Creates the child if it does not yet exist.
528  */
530 
531  bool has_attribute(config_key_type key) const;
532 
534  void merge_attributes(const config &);
535 
536  template<typename... T>
537  void remove_attributes(T... keys) { (remove_attribute(keys), ...); }
538 
539  /**
540  * Copies attributes that exist in the source config.
541  *
542  * @param from Source config to copy attributes from.
543  * @param keys Attribute names.
544  */
545  template<typename... T>
546  void copy_attributes(const config& from, T... keys)
547  {
548  for(const auto& key : {keys...}) {
549  auto* attr = from.get(key);
550  if(attr) {
551  (*this)[key] = *attr;
552  }
553  }
554  }
555 
556  /**
557  * Copies or deletes attributes to match the source config.
558  *
559  * Attributes that do not exist in the source are fully erased rather than
560  * set to the unspecified/default attribute value.
561  *
562  * @param from Source config to copy attributes from.
563  * @param keys Attribute names.
564  */
565  template<typename... T>
566  void copy_or_remove_attributes(const config& from, T... keys)
567  {
568  for(const auto& key : {keys...}) {
569  if(from.has_attribute(key)) {
570  (*this)[key] = from[key];
571  } else {
572  remove_attribute(key);
573  }
574  }
575  }
576 
579 
580  /**
581  * Returns the first child of tag @a key with a @a name attribute
582  * containing @a value.
583  */
584  optional_config_impl<config> find_child(config_key_type key, const std::string &name,
585  const std::string &value);
586 
588  const std::string &value) const
589  { return const_cast<config *>(this)->find_child(key, name, value); }
590 
591  config& find_mandatory_child(config_key_type key, const std::string &name,
592  const std::string &value);
593 
594  const config& find_mandatory_child(config_key_type key, const std::string &name,
595  const std::string &value) const;
596 
597 private:
599 
600 public:
601  template<typename... T>
602  void clear_children(T... keys) { (clear_children_impl(keys), ...); }
603 
604  /**
605  * Moves all the children with tag @a key from @a src to this.
606  */
608 
609  void remove_child(config_key_type key, std::size_t index);
610 
611  /**
612  * Removes all children with tag @a key for which @a p returns true.
613  * If no predicate is provided, all @a key tags will be removed.
614  */
615  void remove_children(config_key_type key, const std::function<bool(const config&)>& p = {});
616 
618 
619  void clear();
620  void clear_all_children();
621  void clear_attributes();
622  bool empty() const;
623 
624  std::string debug() const;
625  std::string hash() const;
626 
627  struct error : public game::error {
628  error(const std::string& message) : game::error(message) {}
629  };
630 
631  struct child_pos
632  {
633  child_pos(child_map::iterator p, std::size_t i) : pos(p), index(i) {}
635  std::size_t index;
636 
637  bool operator==(const child_pos& o) const { return pos == o.pos && index == o.index; }
638  bool operator!=(const child_pos& o) const { return !operator==(o); }
639  };
640 
641  struct any_child
642  {
643  const child_map::key_type &key;
645  any_child(const child_map::key_type *k, config *c): key(*k), cfg(*c) {}
646  };
647 
648  struct const_all_children_iterator;
649 
651  {
653  {
656  const any_child *operator->() const { return &data; }
657  };
658 
660  typedef std::random_access_iterator_tag iterator_category;
664  typedef Itor::difference_type difference_type;
666  explicit all_children_iterator(const Itor &i): i_(i) {}
667 
668  all_children_iterator &operator++() { ++i_; return *this; }
670  this_type &operator--() { --i_; return *this; }
671  this_type operator--(int) { return this_type(i_--); }
672 
673  reference operator*() const;
674  pointer operator->() const { return *this; }
675 
676  bool operator==(const all_children_iterator &i) const { return i_ == i.i_; }
677  bool operator!=(const all_children_iterator &i) const { return i_ != i.i_; }
678  bool operator==(const const_all_children_iterator &i) const { return i_ == i.i_; }
679  bool operator!=(const const_all_children_iterator &i) const { return i_ != i.i_; }
680 
681  friend bool operator<(const this_type& a, const this_type& b) { return a.i_ < b.i_; }
682  friend bool operator<=(const this_type& a, const this_type& b) { return a.i_ <= b.i_; }
683  friend bool operator>=(const this_type& a, const this_type& b) { return a.i_ >= b.i_; }
684  friend bool operator>(const this_type& a, const this_type& b) { return a.i_ > b.i_; }
685 
686  this_type& operator+=(difference_type n) { i_ += n; return *this; }
687  this_type& operator-=(difference_type n) { i_ -= n; return *this; }
688 
689  reference operator[](difference_type n) const { return any_child(&i_[n].pos->first, i_[n].pos->second[i_->index].get()); }
690  friend difference_type operator-(const this_type& a, const this_type& b) { return a.i_ - b.i_; }
691  friend this_type operator-(const this_type& a, difference_type n) { return this_type(a.i_ - n); }
692  friend this_type operator+(const this_type& a, difference_type n) { return this_type(a.i_ + n); }
693  friend this_type operator+(difference_type n, const this_type& a) { return this_type(a.i_ + n); }
694 
695  private:
697 
698  friend class config;
700  };
701 
703  {
705  {
708  const any_child *operator->() const { return &data; }
709  };
710 
711  typedef const any_child value_type;
712  typedef std::random_access_iterator_tag iterator_category;
713  typedef const arrow_helper pointer;
714  typedef const any_child reference;
715  typedef std::vector<child_pos>::const_iterator Itor;
716  typedef Itor::difference_type difference_type;
718  explicit const_all_children_iterator(const Itor &i): i_(i) {}
720 
721  const_all_children_iterator &operator++() { ++i_; return *this; }
723  this_type &operator--() { --i_; return *this; }
724  this_type operator--(int) { return this_type(i_--); }
725 
726  reference operator*() const;
727  pointer operator->() const { return *this; }
728 
729  bool operator==(const const_all_children_iterator &i) const { return i_ == i.i_; }
730  bool operator!=(const const_all_children_iterator &i) const { return i_ != i.i_; }
731  bool operator==(const all_children_iterator &i) const { return i_ == i.i_; }
732  bool operator!=(const all_children_iterator &i) const { return i_ != i.i_; }
733 
734  friend bool operator<(const this_type& a, const this_type& b) { return a.i_ < b.i_; }
735  friend bool operator<=(const this_type& a, const this_type& b) { return a.i_ <= b.i_; }
736  friend bool operator>=(const this_type& a, const this_type& b) { return a.i_ >= b.i_; }
737  friend bool operator>(const this_type& a, const this_type& b) { return a.i_ > b.i_; }
738 
739  this_type& operator+=(difference_type n) { i_ += n; return *this; }
740  this_type& operator-=(difference_type n) { i_ -= n; return *this; }
741 
742  reference operator[](difference_type n) const { return any_child(&i_[n].pos->first, i_[n].pos->second[i_->index].get()); }
743  friend difference_type operator-(const this_type& a, const this_type& b) { return a.i_ - b.i_; }
744  friend this_type operator-(const this_type& a, difference_type n) { return this_type(a.i_ - n); }
745  friend this_type operator+(const this_type& a, difference_type n) { return this_type(a.i_ + n); }
746  friend this_type operator+(difference_type n, const this_type& a) { return this_type(a.i_ + n); }
747 
748  private:
750 
751  friend class config;
752  };
753 
754  /**
755  * @param key the tag name
756  * @param val the contents of the tag
757  * @param pos is the index of the new child in _all_ children.
758  */
759  config& add_child_at_total(config_key_type key, const config &val, std::size_t pos);
760  std::size_t find_total_first_of(config_key_type key, std::size_t start = 0);
761 
762  typedef boost::iterator_range<all_children_iterator> all_children_itors;
763  typedef boost::iterator_range<const_all_children_iterator> const_all_children_itors;
764 
765  /** In-order iteration over all children. */
768 
776 
777 private:
778  template<typename Res>
779  static auto any_tag_view(const child_pos& elem) -> std::pair<const child_map::key_type&, Res>
780  {
781  const auto& [key, list] = *elem.pos;
782  return { key, *list[elem.index] };
783  }
784 
785 public:
786 #ifdef __cpp_explicit_this_parameter // C++23
787 
788  /** In-order iteration over all children. */
789  template<typename Self>
790  auto all_children_view(this Self&& self)
791  { return self.ordered_children | std::views::transform(&config::any_tag_view<Self>); }
792 
793 #else
794 
795  /** In-order iteration over all children. */
796  auto all_children_view() const
797  { return ordered_children | utils::views::transform(&config::any_tag_view<const config&>); }
798 
799  /** In-order iteration over all children. */
801  { return ordered_children | utils::views::transform(&config::any_tag_view<config&>); }
802 
803 #endif // __cpp_explicit_this_parameter
804 
805  /**
806  * A function to get the differences between this object,
807  * and 'c', as another config object.
808  * I.e. calling cfg2.apply_diff(cfg1.get_diff(cfg2))
809  * will make cfg2 identical to cfg1.
810  */
811  config get_diff(const config& c) const;
812  void get_diff(const config& c, config& res) const;
813 
814  /**
815  * The name of the attribute used for tracking diff changes
816  */
817  static const char* diff_track_attribute;
818 
819  /**
820  * A function to apply a diff config onto this config object.
821  *
822  * If the "track" parameter is true, the changes made will be marked in a
823  * magic attribute (defined above) of this and child nodes of this config,
824  * with "new" value indicating an added child, "modified" a modified one,
825  * and "deleted" for the deleted items, *which will not be actually
826  * deleted* (so calling code can easily see what they are).
827  * Use clear_diff_track with the same diff object to clear the tracking
828  * info and actually delete the nodes.
829  */
830  void apply_diff(const config& diff, bool track = false); //throw error
831 
832  /**
833  * Clear any tracking info from a previous apply_diff call with tracking.
834  * This also removes the nodes that are to be deleted, in effect making
835  * apply_diff(c, true); clear_diff_tracking(c);
836  * equivalent to apply_diff(c, false);
837  */
838  void clear_diff_track(const config& diff);
839 
840  /**
841  * Merge config 'c' into this config, overwriting this config's values.
842  */
843  void merge_with(const config& c);
844 
845  /**
846  * Merge config 'c' into this config, preserving this config's values.
847  */
848  void inherit_from(const config& c);
849  /**
850  * Merge the attributes of config 'c' into this config, preserving this config's values.
851  */
852  void inherit_attributes(const config& c);
853 
854  bool matches(const config &filter) const;
855 
856  /**
857  * Append data from another config object to this one.
858  * Attributes in the latter config object will clobber attributes in this one.
859  */
860  void append(const config& cfg);
861  void append(config&& cfg);
862 
863  /**
864  * Adds children from @a cfg.
865  */
866  void append_children(const config &cfg);
867 
868  /**
869  * Adds children from @a cfg.
870  */
871  void append_children(const config &cfg, config_key_type key);
872 
873  /** Moves children with the given name from the given config to this one. */
875 
876  /**
877  * Adds attributes from @a cfg.
878  */
879  void append_attributes(const config &cfg);
880 
881  /**
882  * All children with the given key will be merged
883  * into the first element with that key.
884  */
886 
887  /**
888  * All children with the given key and with equal values
889  * of the specified attribute will be merged into the
890  * element with that key and that value of the attribute
891  */
893 
894  //this is a cheap O(1) operation
895  void swap(config& cfg);
896 
897  /**
898  * Returns true if this object represents valid WML,
899  * i.e. can be saved to disk and again loaded by the WML parser.
900  */
901  bool validate_wml() const;
902 
903  /** A non-owning view over all child tag names. */
904  auto child_name_view() const
905  {
906  return children_ | utils::views::keys;
907  }
908 
909 private:
910  /**
911  * Removes the child at position @a pos of @a l.
912  */
914 
915  /** All the attributes of this node. */
917 
918  /** A list of all children of this node. */
920 
921  std::vector<child_pos> ordered_children;
922 };
923 
924 
927 /** Implement non-member swap function for std::swap (calls @ref config::swap). */
928 void swap(config& lhs, config& rhs);
929 
930 namespace detail
931 {
932  template<typename Key, typename Value, typename... Rest>
933  inline void config_construct_unpack(config& cfg, Key&& key, Value&& val, Rest... fwd)
934  {
935  if constexpr(std::is_same_v<std::decay_t<Value>, config>) {
936  cfg.add_child(std::forward<Key>(key), std::forward<Value>(val));
937  } else {
938  cfg.insert(std::forward<Key>(key), std::forward<Value>(val));
939  }
940 
941  if constexpr(sizeof...(Rest) > 0) {
942  config_construct_unpack(cfg, std::forward<Rest>(fwd)...);
943  }
944  }
945 }
946 
947 template<typename... Args>
948 inline config::config(config_key_type first, Args&&... args)
949 {
950  detail::config_construct_unpack(*this, first, std::forward<Args>(args)...);
951 }
Variant for storing WML attributes.
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:158
void copy_or_remove_attributes(const config &from, T... keys)
Copies or deletes attributes to match the source config.
Definition: config.hpp:566
void merge_children_by_attribute(config_key_type key, config_key_type attribute)
All children with the given key and with equal values of the specified attribute will be merged into ...
Definition: config.cpp:250
const attribute_value & get_old_attribute(config_key_type key, const std::string &old_key, const std::string &in_tag, const std::string &message="") const
Function to handle backward compatibility Get the value of key and if missing try old_key and log a d...
Definition: config.cpp:704
optional_config_impl< const config > find_child(config_key_type key, const std::string &name, const std::string &value) const
Definition: config.hpp:587
void append(const config &cfg)
Append data from another config object to this one.
Definition: config.cpp:188
const attribute_value & get_or(const config_key_type key, const config_key_type default_key) const
Chooses a value.
Definition: config.cpp:687
void remove_attributes(T... keys)
Definition: config.hpp:537
all_children_iterator erase(const all_children_iterator &i)
Definition: config.cpp:634
const_all_children_iterator ordered_begin() const
Definition: config.cpp:860
static auto any_tag_view(const child_pos &elem) -> std::pair< const child_map::key_type &, Res >
Definition: config.hpp:779
boost::iterator_range< const_all_children_iterator > const_all_children_itors
Definition: config.hpp:763
const config & child_or_empty(config_key_type key) const
Returns the first child with the given key, or an empty config if there is none.
Definition: config.cpp:390
std::size_t attribute_count() const
Count the number of non-blank attributes.
Definition: config.cpp:307
config & mandatory_child(config_key_type key, int n=0)
Returns the nth child with the given key, or throws an error if there is none.
Definition: config.cpp:362
void copy_attributes(const config &from, T... keys)
Copies attributes that exist in the source config.
Definition: config.hpp:546
attribute_value & operator[](config_key_type key)
Returns a reference to the attribute with the given key.
Definition: config.cpp:693
void recursive_clear_value(config_key_type key)
Definition: config.cpp:599
bool matches(const config &filter) const
Definition: config.cpp:1190
void remove_child(config_key_type key, std::size_t index)
Definition: config.cpp:639
void merge_children(config_key_type key)
All children with the given key will be merged into the first element with that key.
Definition: config.cpp:235
const_attr_itors attribute_range() const
Definition: config.cpp:756
config_attribute_value attribute_value
Variant for storing WML attributes.
Definition: config.hpp:291
std::size_t child_count(config_key_type key) const
Definition: config.cpp:292
attribute_map values_
All the attributes of this node.
Definition: config.hpp:916
bool validate_wml() const
Returns true if this object represents valid WML, i.e.
Definition: config.cpp:1344
optional_config_impl< const config > get_deprecated_child(config_key_type old_key, const std::string &in_tag, DEP_LEVEL level, const std::string &message) const
Get a deprecated child and log a deprecation message.
Definition: config.cpp:411
auto all_children_view() const
In-order iteration over all children.
Definition: config.hpp:796
void merge_attributes(const config &)
Definition: config.cpp:738
const_all_children_iterator ordered_end() const
Definition: config.cpp:870
boost::iterator_range< child_iterator > child_itors
Definition: config.hpp:281
config & add_child_at(config_key_type key, const config &val, std::size_t index)
Definition: config.cpp:465
config & find_mandatory_child(config_key_type key, const std::string &name, const std::string &value)
Definition: config.cpp:806
const attribute_value & get_deprecated_attribute(config_key_type old_key, const std::string &in_tag, DEP_LEVEL level, const std::string &message) const
Get a deprecated attribute without a direct substitute, and log a deprecation message.
Definition: config.cpp:726
std::vector< std::unique_ptr< config > > child_list
Definition: config.hpp:191
optional_config_impl< config > find_child(config_key_type key, const std::string &name, const std::string &value)
Returns the first child of tag key with a name attribute containing value.
Definition: config.cpp:780
static bool valid_tag(config_key_type name)
Definition: config.cpp:129
boost::iterator_range< attribute_iterator > attr_itors
Definition: config.hpp:359
const_all_children_iterator ordered_cbegin() const
Definition: config.cpp:865
void clear_children(T... keys)
Definition: config.hpp:602
bool has_child(config_key_type key) const
Determine whether a config has a child or not.
Definition: config.cpp:312
bool has_attribute(config_key_type key) const
Definition: config.cpp:157
void merge_with(const config &c)
Merge config 'c' into this config, overwriting this config's values.
Definition: config.cpp:1119
void clear_children_impl(config_key_type key)
Definition: config.cpp:567
std::map< std::string, child_list, std::less<> > child_map
Definition: config.hpp:192
const_child_itors get_deprecated_child_range(config_key_type old_key, const std::string &in_tag, DEP_LEVEL level, const std::string &message) const
Get a deprecated child range and log a deprecation message.
Definition: config.cpp:422
void remove_children(config_key_type key, const std::function< bool(const config &)> &p={})
Removes all children with tag key for which p returns true.
Definition: config.cpp:650
void clear_all_children()
Definition: config.cpp:832
void inherit_from(const config &c)
Merge config 'c' into this config, preserving this config's values.
Definition: config.cpp:1169
const_all_children_itors all_children_range() const
In-order iteration over all children.
Definition: config.cpp:880
static const char * diff_track_attribute
The name of the attribute used for tracking diff changes.
Definition: config.hpp:817
boost::iterator_range< all_children_iterator > all_children_itors
Definition: config.hpp:762
child_itors child_range(config_key_type key)
Definition: config.cpp:268
void append_attributes(const config &cfg)
Adds attributes from cfg.
Definition: config.cpp:174
config & child_or_add(config_key_type key)
Returns a reference to the first child with the given key.
Definition: config.cpp:401
boost::iterator_range< const_attribute_iterator > const_attr_itors
Definition: config.hpp:358
void apply_diff(const config &diff, bool track=false)
A function to apply a diff config onto this config object.
Definition: config.cpp:1022
~config()
Definition: config.cpp:99
std::size_t all_children_count() const
Definition: config.cpp:302
child_map children_
A list of all children of this node.
Definition: config.hpp:919
const_all_children_iterator ordered_cend() const
Definition: config.cpp:875
config & add_child_at_total(config_key_type key, const config &val, std::size_t pos)
Definition: config.cpp:512
void remove_attribute(config_key_type key)
Definition: config.cpp:162
static bool valid_attribute(config_key_type name)
Definition: config.cpp:152
config get_diff(const config &c) const
A function to get the differences between this object, and 'c', as another config object.
Definition: config.cpp:906
config()
Definition: config.cpp:76
std::string debug() const
Definition: config.cpp:1236
attribute_map::value_type attribute
Definition: config.hpp:298
void inherit_attributes(const config &c)
Merge the attributes of config 'c' into this config, preserving this config's values.
Definition: config.cpp:1181
std::size_t find_total_first_of(config_key_type key, std::size_t start=0)
Definition: config.cpp:498
std::vector< child_pos > ordered_children
Definition: config.hpp:921
auto child_name_view() const
A non-owning view over all child tag names.
Definition: config.hpp:904
void clear_diff_track(const config &diff)
Clear any tracking info from a previous apply_diff call with tracking.
Definition: config.cpp:1083
std::map< std::string, attribute_value, std::less<> > attribute_map
Definition: config.hpp:297
void swap(config &cfg)
Definition: config.cpp:1332
void append_children_by_move(config &cfg, config_key_type key)
Moves children with the given name from the given config to this one.
Definition: config.cpp:224
boost::iterator_range< const_child_iterator > const_child_itors
Definition: config.hpp:282
void append_children(const config &cfg)
Adds children from cfg.
Definition: config.cpp:167
auto all_children_view()
In-order iteration over all children.
Definition: config.hpp:800
void clear_attributes()
Definition: config.cpp:839
void insert(config_key_type key, T &&value)
Inserts an attribute into the config.
Definition: config.hpp:520
bool empty() const
Definition: config.cpp:845
void splice_children(config &src, config_key_type key)
Moves all the children with tag key from src to this.
Definition: config.cpp:577
void clear()
Definition: config.cpp:824
const attribute_value * get(config_key_type key) const
Returns a pointer to the attribute with the given key or nullptr if it does not exist.
Definition: config.cpp:681
std::string hash() const
Definition: config.cpp:1279
friend bool operator==(const config &a, const config &b)
Definition: config.cpp:1358
optional_config_impl< config > optional_child(config_key_type key, int n=0)
Equivalent to mandatory_child, but returns an empty optional if the nth child was not found.
Definition: config.cpp:380
config & operator=(const config &)
Definition: config.cpp:104
config & add_child(config_key_type key)
Definition: config.cpp:436
optional_config_impl()=default
T * operator->() const
Definition: config.hpp:115
optional_config_impl(utils::nullopt_t)
Definition: config.hpp:64
utils::const_clone_t< config_attribute_value, T > & operator[](config_key_type key)
Definition: config.hpp:127
bool has_value() const
Definition: config.hpp:86
optional_config_impl< T > & operator=(T &new_ref)
Definition: config.hpp:80
T & operator*() const
Definition: config.hpp:121
T * ptr() const
Returns a pointer to the referenced object or nullptr if no reference is held.
Definition: config.hpp:106
optional_config_impl(T &ref)
Definition: config.hpp:59
bool tested() const
Definition: config.hpp:137
T & value() const
Definition: config.hpp:69
A simple wrapper class for optional reference types.
std::string_view config_key_type
Definition: config.hpp:48
bool operator!=(const config &a, const config &b)
Definition: config.hpp:153
std::ostream & operator<<(std::ostream &, const config &)
Definition: config.cpp:1243
void swap(config &lhs, config &rhs)
Implement non-member swap function for std::swap (calls config::swap).
Definition: config.cpp:1339
bool operator==(const config &, const config &)
Definition: config.cpp:1358
Definitions for the interface to Wesnoth Markup Language (WML).
DEP_LEVEL
See https://wiki.wesnoth.org/CompatibilityStandards for more info.
Definition: deprecation.hpp:21
std::size_t i
Definition: function.cpp:1029
void config_construct_unpack(config &cfg, Key &&key, Value &&val, Rest... fwd)
Definition: config.hpp:933
EXIT_STATUS start(bool clear_id, const std::string &filename, bool take_screenshot, const std::string &screenshot_filename)
Main interface for launching the editor from the title screen.
std::size_t index(std::string_view str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:70
constexpr auto transform
Definition: ranges.hpp:41
constexpr auto keys
Definition: ranges.hpp:39
constexpr auto filter
Definition: ranges.hpp:38
typename const_clone< D, S >::type const_clone_t
Definition: const_clone.hpp:60
std::string::const_iterator iterator
Definition: tokenizer.hpp:25
rect src
Non-transparent portion of the surface to compose.
const any_child * operator->() const
Definition: config.hpp:656
arrow_helper(const all_children_iterator &i)
Definition: config.hpp:655
friend difference_type operator-(const this_type &a, const this_type &b)
Definition: config.hpp:690
all_children_iterator this_type
Definition: config.hpp:665
pointer operator->() const
Definition: config.hpp:674
std::vector< child_pos >::iterator Itor
Definition: config.hpp:663
all_children_iterator & operator++()
Definition: config.hpp:668
reference operator[](difference_type n) const
Definition: config.hpp:689
reference operator*() const
Definition: config.cpp:850
bool operator==(const all_children_iterator &i) const
Definition: config.hpp:676
friend this_type operator-(const this_type &a, difference_type n)
Definition: config.hpp:691
this_type operator--(int)
Definition: config.hpp:671
this_type & operator-=(difference_type n)
Definition: config.hpp:687
bool operator==(const const_all_children_iterator &i) const
Definition: config.hpp:678
std::random_access_iterator_tag iterator_category
Definition: config.hpp:660
friend bool operator>=(const this_type &a, const this_type &b)
Definition: config.hpp:683
friend bool operator>(const this_type &a, const this_type &b)
Definition: config.hpp:684
friend this_type operator+(const this_type &a, difference_type n)
Definition: config.hpp:692
this_type & operator+=(difference_type n)
Definition: config.hpp:686
friend bool operator<=(const this_type &a, const this_type &b)
Definition: config.hpp:682
friend bool operator<(const this_type &a, const this_type &b)
Definition: config.hpp:681
bool operator!=(const all_children_iterator &i) const
Definition: config.hpp:677
all_children_iterator(const Itor &i)
Definition: config.hpp:666
bool operator!=(const const_all_children_iterator &i) const
Definition: config.hpp:679
all_children_iterator operator++(int)
Definition: config.hpp:669
friend this_type operator+(difference_type n, const this_type &a)
Definition: config.hpp:693
Itor::difference_type difference_type
Definition: config.hpp:664
any_child(const child_map::key_type *k, config *c)
Definition: config.hpp:645
const child_map::key_type & key
Definition: config.hpp:643
config & cfg
Definition: config.hpp:644
attribute_iterator & operator--()
Definition: config.hpp:313
bool operator!=(const attribute_iterator &i) const
Definition: config.hpp:320
attribute_iterator operator--(int)
Definition: config.hpp:314
std::bidirectional_iterator_tag iterator_category
Definition: config.hpp:304
bool operator==(const attribute_iterator &i) const
Definition: config.hpp:319
bool operator!=(const const_attribute_iterator &i) const
Definition: config.hpp:322
reference operator*() const
Definition: config.hpp:316
Itor::difference_type difference_type
Definition: config.hpp:308
pointer operator->() const
Definition: config.hpp:317
bool operator==(const const_attribute_iterator &i) const
Definition: config.hpp:321
attribute_map::iterator Itor
Definition: config.hpp:307
attribute_iterator operator++(int)
Definition: config.hpp:312
attribute_iterator(const Itor &i)
Definition: config.hpp:309
attribute_iterator & operator++()
Definition: config.hpp:311
friend Itor::difference_type operator-(const this_type &a, const this_type &b)
Definition: config.hpp:229
std::random_access_iterator_tag iterator_category
Definition: config.hpp:199
friend this_type operator-(const this_type &a, Itor::difference_type n)
Definition: config.hpp:230
child_iterator & operator++()
Definition: config.hpp:207
bool operator==(const const_child_iterator &i) const
Definition: config.hpp:217
Itor::difference_type difference_type
Definition: config.hpp:203
bool operator==(const child_iterator &i) const
Definition: config.hpp:215
this_type & operator-=(Itor::difference_type n)
Definition: config.hpp:226
child_list::iterator Itor
Definition: config.hpp:202
child_iterator(const Itor &i)
Definition: config.hpp:205
reference operator*() const
Definition: config.hpp:212
bool operator!=(const const_child_iterator &i) const
Definition: config.hpp:218
pointer operator->() const
Definition: config.hpp:213
child_iterator operator--(int)
Definition: config.hpp:210
config & operator[](Itor::difference_type n) const
Definition: config.hpp:228
friend this_type operator+(Itor::difference_type n, const this_type &a)
Definition: config.hpp:232
friend this_type operator+(const this_type &a, Itor::difference_type n)
Definition: config.hpp:231
child_iterator operator++(int)
Definition: config.hpp:208
friend bool operator>=(const this_type &a, const this_type &b)
Definition: config.hpp:222
friend bool operator>(const this_type &a, const this_type &b)
Definition: config.hpp:223
this_type & operator+=(Itor::difference_type n)
Definition: config.hpp:225
bool operator!=(const child_iterator &i) const
Definition: config.hpp:216
friend bool operator<=(const this_type &a, const this_type &b)
Definition: config.hpp:221
friend bool operator<(const this_type &a, const this_type &b)
Definition: config.hpp:220
child_iterator & operator--()
Definition: config.hpp:209
child_iterator this_type
Definition: config.hpp:204
bool operator==(const child_pos &o) const
Definition: config.hpp:637
std::size_t index
Definition: config.hpp:635
bool operator!=(const child_pos &o) const
Definition: config.hpp:638
child_pos(child_map::iterator p, std::size_t i)
Definition: config.hpp:633
child_map::iterator pos
Definition: config.hpp:634
arrow_helper(const const_all_children_iterator &i)
Definition: config.hpp:707
const_all_children_iterator this_type
Definition: config.hpp:717
friend difference_type operator-(const this_type &a, const this_type &b)
Definition: config.hpp:743
const_all_children_iterator(const all_children_iterator &i)
Definition: config.hpp:719
const_all_children_iterator(const Itor &i)
Definition: config.hpp:718
const_all_children_iterator operator++(int)
Definition: config.hpp:722
Itor::difference_type difference_type
Definition: config.hpp:716
reference operator[](difference_type n) const
Definition: config.hpp:742
std::vector< child_pos >::const_iterator Itor
Definition: config.hpp:715
bool operator==(const const_all_children_iterator &i) const
Definition: config.hpp:729
friend this_type operator-(const this_type &a, difference_type n)
Definition: config.hpp:744
std::random_access_iterator_tag iterator_category
Definition: config.hpp:712
bool operator!=(const const_all_children_iterator &i) const
Definition: config.hpp:730
this_type & operator+=(difference_type n)
Definition: config.hpp:739
bool operator!=(const all_children_iterator &i) const
Definition: config.hpp:732
bool operator==(const all_children_iterator &i) const
Definition: config.hpp:731
friend bool operator>=(const this_type &a, const this_type &b)
Definition: config.hpp:736
friend bool operator>(const this_type &a, const this_type &b)
Definition: config.hpp:737
friend this_type operator+(const this_type &a, difference_type n)
Definition: config.hpp:745
friend bool operator<=(const this_type &a, const this_type &b)
Definition: config.hpp:735
friend bool operator<(const this_type &a, const this_type &b)
Definition: config.hpp:734
const_all_children_iterator & operator++()
Definition: config.hpp:721
friend this_type operator+(difference_type n, const this_type &a)
Definition: config.hpp:746
this_type & operator-=(difference_type n)
Definition: config.hpp:740
bool operator==(const attribute_iterator &i) const
Definition: config.hpp:351
const_attribute_iterator & operator++()
Definition: config.hpp:340
const_attribute_iterator operator--(int)
Definition: config.hpp:344
const_attribute_iterator operator++(int)
Definition: config.hpp:341
Itor::difference_type difference_type
Definition: config.hpp:336
const_attribute_iterator & operator--()
Definition: config.hpp:343
const attribute & reference
Definition: config.hpp:334
const_attribute_iterator(const Itor &i)
Definition: config.hpp:337
const_attribute_iterator(attribute_iterator &i)
Definition: config.hpp:338
const attribute * pointer
Definition: config.hpp:333
reference operator*() const
Definition: config.hpp:346
attribute_map::const_iterator Itor
Definition: config.hpp:335
std::bidirectional_iterator_tag iterator_category
Definition: config.hpp:332
bool operator!=(const attribute_iterator &i) const
Definition: config.hpp:352
bool operator!=(const const_attribute_iterator &i) const
Definition: config.hpp:350
bool operator==(const const_attribute_iterator &i) const
Definition: config.hpp:349
this_type & operator-=(Itor::difference_type n)
Definition: config.hpp:269
friend Itor::difference_type operator-(const this_type &a, const this_type &b)
Definition: config.hpp:272
const_child_iterator(const Itor &i)
Definition: config.hpp:247
friend this_type operator-(const this_type &a, Itor::difference_type n)
Definition: config.hpp:273
bool operator==(const const_child_iterator &i) const
Definition: config.hpp:258
std::random_access_iterator_tag iterator_category
Definition: config.hpp:241
pointer operator->() const
Definition: config.hpp:256
const_child_iterator operator++(int)
Definition: config.hpp:251
const_child_iterator this_type
Definition: config.hpp:246
bool operator==(const child_iterator &i) const
Definition: config.hpp:260
const_child_iterator operator--(int)
Definition: config.hpp:253
const config & operator[](Itor::difference_type n) const
Definition: config.hpp:271
Itor::difference_type difference_type
Definition: config.hpp:245
const_child_iterator(const child_iterator &i)
Definition: config.hpp:248
const_child_iterator & operator++()
Definition: config.hpp:250
const_child_iterator & operator--()
Definition: config.hpp:252
friend this_type operator+(Itor::difference_type n, const this_type &a)
Definition: config.hpp:275
friend this_type operator+(const this_type &a, Itor::difference_type n)
Definition: config.hpp:274
const config * pointer
Definition: config.hpp:242
bool operator!=(const child_iterator &i) const
Definition: config.hpp:261
friend bool operator>=(const this_type &a, const this_type &b)
Definition: config.hpp:265
friend bool operator>(const this_type &a, const this_type &b)
Definition: config.hpp:266
const config & reference
Definition: config.hpp:243
reference operator*() const
Definition: config.hpp:255
bool operator!=(const const_child_iterator &i) const
Definition: config.hpp:259
friend bool operator<=(const this_type &a, const this_type &b)
Definition: config.hpp:264
this_type & operator+=(Itor::difference_type n)
Definition: config.hpp:268
friend bool operator<(const this_type &a, const this_type &b)
Definition: config.hpp:263
child_list::const_iterator Itor
Definition: config.hpp:244
error(const std::string &message)
Definition: config.hpp:628
Base class for all the errors encountered by the engine.
Definition: exceptions.hpp:29
std::string message
Definition: exceptions.hpp:30
mock_char c
mock_party p
static map_location::direction n
#define b