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