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