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