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