The Battle for Wesnoth  1.15.10+dev
variable.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 by David White <dave@whitevine.net>
3  Copyright (C) 2005 - 2018 by Philippe Plantier <ayin@anathas.org>
4 
5  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY.
13 
14  See the COPYING file for more details.
15 */
16 
17 #pragma once
18 
19 #include "config.hpp"
20 #include "map/location.hpp"
21 #include "variable_info.hpp"
22 
23 #include <utility>
24 
25 class unit_map;
26 
28  const config& cfg_;
29 public:
30  config_variable_set(const config& cfg) : cfg_(cfg) {}
31  virtual config::attribute_value get_variable_const(const std::string &id) const;
32  virtual variable_access_const get_variable_access_read(const std::string& varname) const;
33 };
34 
35 /**
36  * A variable-expanding proxy for the config class. This class roughly behaves
37  * as a constant config object, but automatically expands variables.
38  *
39  * When dealing with a vconfig, keep in mind its lifetime. By default, vconfigs
40  * do not maintain a copy their data; if you need a vconfig to stick around,
41  * either construct it with manage_memory=true or call make_safe(). This will
42  * cause the vconfig to make a copy of the underlying config object.
43  */
44 class vconfig
45 {
46 private:
47 
48  vconfig();
49  vconfig(const config & cfg, const std::shared_ptr<const config> & cache);
50  vconfig(const config& cfg, const std::shared_ptr<const config> & cache, const variable_set& variables);
51 public:
52  /**
53  * Constructor from a config.
54  * Equivalent to vconfig(cfg, false).
55  * Do not use if the vconfig will persist after @a cfg is destroyed!
56  */
57  explicit vconfig(const config &cfg);
58  explicit vconfig(config &&cfg);
59  // Construct a vconfig referencing a non-default set of variables.
60  // Note that the vconfig does NOT take ownership of these variables,
61  // so you need to make sure that their scope encloses the vconfig's scope!
62  vconfig(const config& cfg, const variable_set& variables);
63  vconfig(const config &cfg, bool manage_memory, const variable_set* variables = nullptr);
64  ~vconfig();
65 
66  static vconfig empty_vconfig(); // Valid to dereference. Contains nothing
67  static vconfig unconstructed_vconfig(); // Must not be dereferenced
68 
69  /** A vconfig evaluates to true iff it can be dereferenced. */
70  explicit operator bool() const { return !null(); }
71 
72  bool null() const { assert(cfg_); return cfg_ == &default_empty_config; }
73  /** instruct the vconfig to make a private copy of its underlying data. */
74  const vconfig& make_safe() const;
75  const config& get_config() const { return *cfg_; }
76  config get_parsed_config() const;
77 
78  typedef std::vector<vconfig> child_list;
79  child_list get_children(const std::string& key) const;
80  std::size_t count_children(const std::string& key) const;
81  vconfig child(const std::string& key) const;
82  bool has_child(const std::string& key) const;
83 
84  /**
85  * Note: vconfig::operator[] returns const, and this should not be changed
86  * because vconfig is often used as a drop-in replacement for config, and
87  * this const will properly warn you if you try to assign vcfg["key"]=val;
88  *
89  * Note: The following construction is unsafe:
90  * const std::string& temp = vcfg["foo"];
91  * This binds temp to a member of a temporary t_string. The lifetime of the
92  * temporary is not extended by this reference binding and the temporary's
93  * lifetime ends which causes UB. Instead use:
94  * const std::string temp = vcfg["foo"];
95  */
96  const config::attribute_value operator[](const std::string &key) const
97  { return expand(key); }
98  config::attribute_value expand(const std::string&) const; /** < Synonym for operator[] */
99  bool has_attribute(const std::string& key) const { return cfg_->has_attribute(key); }
100  bool empty() const { return (null() || cfg_->empty()); }
101 
103  {
105 
106  typedef const config::attribute value_type;
107  typedef std::bidirectional_iterator_tag iterator_category;
108  typedef int difference_type;
109  typedef const pointer_proxy pointer;
112  explicit attribute_iterator(const Itor &i, const variable_set& vars): i_(i), variables_(&vars) {}
113 
114  attribute_iterator &operator++() { ++i_; return *this; }
115  attribute_iterator operator++(int) { return attribute_iterator(i_++, *variables_); }
116 
117  attribute_iterator &operator--() { --i_; return *this; }
118  attribute_iterator operator--(int) { return attribute_iterator(i_--, *variables_); }
119 
120  reference operator*() const;
121  pointer operator->() const;
122 
123  bool operator==(const attribute_iterator &i) const { return i_ == i.i_; }
124  bool operator!=(const attribute_iterator &i) const { return i_ != i.i_; }
125 
126  private:
127  Itor i_;
129  };
130 
131  boost::iterator_range<attribute_iterator> attribute_range() {
133  return boost::make_iterator_range(attribute_iterator(range.begin(), *variables_), attribute_iterator(range.end(), *variables_));
134  }
135 
137  {
139 
140  typedef const std::pair<std::string, vconfig> value_type;
141  typedef std::bidirectional_iterator_tag iterator_category;
142  typedef int difference_type;
143  typedef const pointer_proxy pointer;
144  typedef const value_type reference;
146  explicit all_children_iterator(const Itor &i, const variable_set& vars);
147  all_children_iterator(const Itor &i, const variable_set& vars, const std::shared_ptr<const config> & cache);
148 
149  all_children_iterator& operator++();
150  all_children_iterator operator++(int);
151  all_children_iterator& operator--();
152  all_children_iterator operator--(int);
153 
154  reference operator*() const;
155  pointer operator->() const;
156 
157  std::string get_key() const;
158  vconfig get_child() const;
159  void disable_insertion() { inner_index_ = -1; }
160 
161  bool operator==(const all_children_iterator &i) const;
162  bool operator!=(const all_children_iterator &i) const
163  { return !operator==(i); }
164 
165  private:
166  Itor i_;
167  /*
168  if wa have game variables
169  [a] b = 1 [/a]
170  [a] b = 4 [/a]
171  [a] b = 6 [/a]
172  we want to expand [insert_tag] variable = a name = "u" [/insert_tag] to
173  [u] b = 1 [/u]
174  [u] b = 4 [/u]
175  [u] b = 6 [/u]
176  in this case inner_index_ points to the index in 'a' we are currently processing.
177  */
179  std::shared_ptr<const config> cache_;
181  };
182 
183  struct recursion_error : public config::error {
184  recursion_error(const std::string& msg) : error(msg) {}
185  };
186 
187  /** In-order iteration over all children. */
188  all_children_iterator ordered_begin() const;
189  all_children_iterator ordered_end() const;
190  boost::iterator_range<all_children_iterator> all_ordered() const {
191  return boost::make_iterator_range(ordered_begin(), ordered_end());
192  }
193 
194 private:
195  /** Returns true if *this has made a copy of its config. */
196  bool memory_managed() const { return static_cast<bool>(cache_); }
197 
198  /**
199  * Keeps a copy of our config alive when we manage our own memory.
200  * If this is not null, then cfg_ points to *cache_ or a child of *cache_.
201  */
202  mutable std::shared_ptr<const config> cache_;
203  /** Used to access our config (original or copy, as appropriate). */
204  mutable const config* cfg_;
207 };
208 
210 {
213  value_type *operator->() const { return &p; }
214 };
215 
217 {
220  value_type *operator->() const { return &p; }
221 };
222 
223 
225 {
226 public:
227  scoped_wml_variable(const std::string& var_name);
228  virtual ~scoped_wml_variable();
229  const std::string& name() const { return var_name_; }
230  virtual void activate() = 0;
231  config &store(const config &var_value = config());
232  bool activated() const { return activated_; }
233 private:
235  const std::string var_name_;
237 };
238 
240 {
241 public:
242  scoped_weapon_info(const std::string& var_name, const config &data)
243  : scoped_wml_variable(var_name), data_(data) {}
244  void activate();
245 private:
246  const config& data_;
247 };
248 
250 {
251 public:
252  scoped_xy_unit(const std::string& var_name, map_location loc, const unit_map& umap)
253  : scoped_wml_variable(var_name), loc_(loc), umap_(umap) {}
254  void activate();
255 private:
257  const unit_map& umap_;
258 };
259 
261 {
262 public:
263  scoped_recall_unit(const std::string& var_name, const std::string& player,
264  unsigned int recall_index) : scoped_wml_variable(var_name), player_(player),
265  recall_index_(recall_index) {}
266  void activate();
267 private:
268  const std::string player_;
269  unsigned int recall_index_;
270 };
recursion_error(const std::string &msg)
Definition: variable.hpp:184
const config::attribute_value operator[](const std::string &key) const
Note: vconfig::operator[] returns const, and this should not be changed because vconfig is often used...
Definition: variable.hpp:96
virtual config::attribute_value get_variable_const(const std::string &id) const
Definition: variable.cpp:65
const map_location loc_
Definition: variable.hpp:256
std::shared_ptr< const config > cache_
Definition: variable.hpp:179
config::const_all_children_iterator Itor
Definition: variable.hpp:145
Variant for storing WML attributes.
const variable_set * variables_
Definition: variable.hpp:180
static l_noret error(LoadState *S, const char *why)
Definition: lundump.cpp:40
bool has_attribute(config_key_type key) const
Definition: config.cpp:207
virtual variable_access_const get_variable_access_read(const std::string &varname) const
Definition: variable.cpp:75
bool has_attribute(const std::string &key) const
< Synonym for operator[]
Definition: variable.hpp:99
config::const_attribute_iterator Itor
Definition: variable.hpp:111
attribute_map::value_type attribute
Definition: config.hpp:220
std::bidirectional_iterator_tag iterator_category
Definition: variable.hpp:107
const config::attribute reference
Definition: variable.hpp:110
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:109
const pointer_proxy pointer
Definition: variable.hpp:143
scoped_recall_unit(const std::string &var_name, const std::string &player, unsigned int recall_index)
Definition: variable.hpp:263
Definitions for the interface to Wesnoth Markup Language (WML).
bool empty() const
Definition: variable.hpp:100
std::bidirectional_iterator_tag iterator_category
Definition: variable.hpp:141
const_attr_itors attribute_range() const
Definition: config.cpp:833
unsigned int recall_index_
Definition: variable.hpp:269
map_location loc_
const config * cfg_
Used to access our config (original or copy, as appropriate).
Definition: variable.hpp:204
const config::attribute value_type
Definition: variable.hpp:104
const config & data_
Definition: variable.hpp:246
const std::string & name() const
Definition: variable.hpp:229
bool memory_managed() const
Returns true if *this has made a copy of its config.
Definition: variable.hpp:196
bool activated() const
Definition: variable.hpp:232
boost::iterator_range< attribute_iterator > attribute_range()
Definition: variable.hpp:131
boost::iterator_range< const_attribute_iterator > const_attr_itors
Definition: config.hpp:280
std::shared_ptr< const config > cache_
Keeps a copy of our config alive when we manage our own memory.
Definition: variable.hpp:202
Encapsulates the map of the game.
Definition: location.hpp:37
attribute_iterator & operator--()
Definition: variable.hpp:117
attribute_iterator operator--(int)
Definition: variable.hpp:118
std::size_t i
Definition: function.cpp:934
mock_party p
bool operator==(const config &a, const config &b)
Definition: config.cpp:1450
static tcache cache
Definition: minimap.cpp:123
scoped_weapon_info(const std::string &var_name, const config &data)
Definition: variable.hpp:242
const config & get_child(const std::string &key)
Definition: general.cpp:213
attribute_iterator & operator++()
Definition: variable.hpp:114
bool operator!=(const attribute_iterator &i) const
Definition: variable.hpp:124
const std::string player_
Definition: variable.hpp:268
scoped_xy_unit(const std::string &var_name, map_location loc, const unit_map &umap)
Definition: variable.hpp:252
Information on a WML variable.
const pointer_proxy pointer
Definition: variable.hpp:109
const std::pair< std::string, vconfig > value_type
Definition: variable.hpp:138
bool operator==(const attribute_iterator &i) const
Definition: variable.hpp:123
const config & cfg_
Definition: variable.hpp:28
A variable-expanding proxy for the config class.
Definition: variable.hpp:44
const config & get_config() const
Definition: variable.hpp:75
const variable_set * variables_
Definition: variable.hpp:128
Container associating units to locations.
Definition: map.hpp:97
const variable_set * variables_
Definition: variable.hpp:205
attribute_iterator operator++(int)
Definition: variable.hpp:115
static const config default_empty_config
Definition: variable.hpp:206
bool operator!=(const all_children_iterator &i) const
Definition: variable.hpp:162
attribute_iterator(const Itor &i, const variable_set &vars)
Definition: variable.hpp:112
std::vector< vconfig > child_list
Definition: variable.hpp:78
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:59
bool null() const
Definition: variable.hpp:72
const std::string var_name_
Definition: variable.hpp:235
bool empty() const
Definition: config.cpp:916
const value_type reference
Definition: variable.hpp:144
boost::iterator_range< all_children_iterator > all_ordered() const
Definition: variable.hpp:190
const unit_map & umap_
Definition: variable.hpp:257
config_variable_set(const config &cfg)
Definition: variable.hpp:30