The Battle for Wesnoth  1.15.3+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 /*
49  * Starting with the rc of gcc 4.6 the code failed to compile due to the
50  * missing default constructor for vconfig. Not entirely sure whether it's a
51  * bug in gcc or not. For now make the code conditional.
52  */
53 #if __GNUC__ == 4 && __GNUC_MINOR__ == 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
54  template<class T1, class T2>
55  friend class std::pair;
56 #endif
57 
58  vconfig();
59  vconfig(const config & cfg, const std::shared_ptr<const config> & cache);
60  vconfig(const config& cfg, const std::shared_ptr<const config> & cache, const variable_set& variables);
61 public:
62  /// Constructor from a config.
63  /// Equivalent to vconfig(cfg, false).
64  /// Do not use if the vconfig will persist after @a cfg is destroyed!
65  explicit vconfig(const config &cfg);// : cache_(), cfg_(&cfg) {}
66  explicit vconfig(config &&cfg);// : cache_(new config(std::move(cfg))), cfg_(cache_.get()) { }
67  // Construct a vconfig referencing a non-default set of variables.
68  // Note that the vconfig does NOT take ownership of these variables,
69  // so you need to make sure that their scope encloses the vconfig's scope!
70  vconfig(const config& cfg, const variable_set& variables);
71  vconfig(const config &cfg, bool manage_memory, const variable_set* variables = nullptr);
72  ~vconfig();
73 
74  static vconfig empty_vconfig(); // Valid to dereference. Contains nothing
75  static vconfig unconstructed_vconfig(); // Must not be dereferenced
76 
77  /// A vconfig evaluates to true iff it can be dereferenced.
78  explicit operator bool() const { return !null(); }
79 
80  bool null() const { assert(cfg_); return cfg_ == &default_empty_config; }
81  const vconfig& make_safe() const; //!< instruct the vconfig to make a private copy of its underlying data.
82  const config& get_config() const { return *cfg_; }
83  config get_parsed_config() const;
84 
85  typedef std::vector<vconfig> child_list;
86  child_list get_children(const std::string& key) const;
87  std::size_t count_children(const std::string& key) const;
88  vconfig child(const std::string& key) const;
89  bool has_child(const std::string& key) const;
90 
91  /**
92  * Note: vconfig::operator[] returns const, and this should not be changed
93  * because vconfig is often used as a drop-in replacement for config, and
94  * this const will properly warn you if you try to assign vcfg["key"]=val;
95  *
96  * Note: The following construction is unsafe:
97  * const std::string& temp = vcfg["foo"];
98  * This binds temp to a member of a temporary t_string. The lifetime of the
99  * temporary is not extended by this reference binding and the temporary's
100  * lifetime ends which causes UB. Instead use:
101  * const std::string temp = vcfg["foo"];
102  */
103  const config::attribute_value operator[](const std::string &key) const
104  { return expand(key); }
105  config::attribute_value expand(const std::string&) const; /** < Synonym for operator[] */
106  bool has_attribute(const std::string& key) const { return cfg_->has_attribute(key); }
107  bool empty() const { return (null() || cfg_->empty()); }
108 
110  {
112 
113  typedef const config::attribute value_type;
114  typedef std::bidirectional_iterator_tag iterator_category;
115  typedef int difference_type;
116  typedef const pointer_proxy pointer;
119  explicit attribute_iterator(const Itor &i, const variable_set& vars): i_(i), variables_(&vars) {}
120 
121  attribute_iterator &operator++() { ++i_; return *this; }
122  attribute_iterator operator++(int) { return attribute_iterator(i_++, *variables_); }
123 
124  attribute_iterator &operator--() { --i_; return *this; }
125  attribute_iterator operator--(int) { return attribute_iterator(i_--, *variables_); }
126 
127  reference operator*() const;
128  pointer operator->() const;
129 
130  bool operator==(const attribute_iterator &i) const { return i_ == i.i_; }
131  bool operator!=(const attribute_iterator &i) const { return i_ != i.i_; }
132 
133  private:
134  Itor i_;
136  };
137 
138  boost::iterator_range<attribute_iterator> attribute_range() {
140  return boost::make_iterator_range(attribute_iterator(range.begin(), *variables_), attribute_iterator(range.end(), *variables_));
141  }
142 
144  {
146 
147  typedef const std::pair<std::string, vconfig> value_type;
148  typedef std::bidirectional_iterator_tag iterator_category;
149  typedef int difference_type;
150  typedef const pointer_proxy pointer;
151  typedef const value_type reference;
153  explicit all_children_iterator(const Itor &i, const variable_set& vars);
154  all_children_iterator(const Itor &i, const variable_set& vars, const std::shared_ptr<const config> & cache);
155 
156  all_children_iterator& operator++();
157  all_children_iterator operator++(int);
158  all_children_iterator& operator--();
159  all_children_iterator operator--(int);
160 
161  reference operator*() const;
162  pointer operator->() const;
163 
164  std::string get_key() const;
165  vconfig get_child() const;
166  void disable_insertion() { inner_index_ = -1; }
167 
168  bool operator==(const all_children_iterator &i) const;
169  bool operator!=(const all_children_iterator &i) const
170  { return !operator==(i); }
171 
172  private:
173  Itor i_;
174  /*
175  if wa have game variables
176  [a] b = 1 [/a]
177  [a] b = 4 [/a]
178  [a] b = 6 [/a]
179  we want to expand [insert_tag] variable = a name = "u" [/insert_tag] to
180  [u] b = 1 [/u]
181  [u] b = 4 [/u]
182  [u] b = 6 [/u]
183  in this case inner_index_ points to the index in 'a' we are currently processing.
184  */
186  std::shared_ptr<const config> cache_;
188  };
189 
190  struct recursion_error : public config::error {
191  recursion_error(const std::string& msg) : error(msg) {}
192  };
193 
194  /** In-order iteration over all children. */
195  all_children_iterator ordered_begin() const;
196  all_children_iterator ordered_end() const;
197  boost::iterator_range<all_children_iterator> all_ordered() const {
198  return boost::make_iterator_range(ordered_begin(), ordered_end());
199  }
200 
201 private:
202  /// Returns true if *this has made a copy of its config.
203  bool memory_managed() const { return static_cast<bool>(cache_); }
204 
205  /// Keeps a copy of our config alive when we manage our own memory.
206  /// If this is not null, then cfg_ points to *cache_ or a child of *cache_.
207  mutable std::shared_ptr<const config> cache_;
208  /// Used to access our config (original or copy, as appropriate).
209  mutable const config* cfg_;
212 };
213 
215 {
218  value_type *operator->() const { return &p; }
219 };
220 
222 {
225  value_type *operator->() const { return &p; }
226 };
227 
228 
230 {
231 public:
232  scoped_wml_variable(const std::string& var_name);
233  virtual ~scoped_wml_variable();
234  const std::string& name() const { return var_name_; }
235  virtual void activate() = 0;
236  config &store(const config &var_value = config());
237  bool activated() const { return activated_; }
238 private:
240  const std::string var_name_;
242 };
243 
245 {
246 public:
247  scoped_weapon_info(const std::string& var_name, const config &data)
248  : scoped_wml_variable(var_name), data_(data) {}
249  void activate();
250 private:
251  const config& data_;
252 };
253 
255 {
256 public:
257  scoped_xy_unit(const std::string& var_name, map_location loc, const unit_map& umap)
258  : scoped_wml_variable(var_name), loc_(loc), umap_(umap) {}
259  void activate();
260 private:
262  const unit_map& umap_;
263 };
264 
266 {
267 public:
268  scoped_recall_unit(const std::string& var_name, const std::string& player,
269  unsigned int recall_index) : scoped_wml_variable(var_name), player_(player),
270  recall_index_(recall_index) {}
271  void activate();
272 private:
273  const std::string player_;
274  unsigned int recall_index_;
275 };
recursion_error(const std::string &msg)
Definition: variable.hpp:191
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:103
virtual config::attribute_value get_variable_const(const std::string &id) const
Definition: variable.cpp:66
const map_location loc_
Definition: variable.hpp:261
std::shared_ptr< const config > cache_
Definition: variable.hpp:186
config::const_all_children_iterator Itor
Definition: variable.hpp:152
Variant for storing WML attributes.
const variable_set * variables_
Definition: variable.hpp:187
static l_noret error(LoadState *S, const char *why)
Definition: lundump.cpp:39
bool has_attribute(config_key_type key) const
Definition: config.cpp:213
virtual variable_access_const get_variable_access_read(const std::string &varname) const
Definition: variable.cpp:76
bool has_attribute(const std::string &key) const
< Synonym for operator[]
Definition: variable.hpp:106
config::const_attribute_iterator Itor
Definition: variable.hpp:118
attribute_map::value_type attribute
Definition: config.hpp:226
std::bidirectional_iterator_tag iterator_category
Definition: variable.hpp:114
const config::attribute reference
Definition: variable.hpp:117
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:150
scoped_recall_unit(const std::string &var_name, const std::string &player, unsigned int recall_index)
Definition: variable.hpp:268
Definitions for the interface to Wesnoth Markup Language (WML).
bool empty() const
Definition: variable.hpp:107
std::bidirectional_iterator_tag iterator_category
Definition: variable.hpp:148
const_attr_itors attribute_range() const
Definition: config.cpp:809
unsigned int recall_index_
Definition: variable.hpp:274
map_location loc_
const config * cfg_
Used to access our config (original or copy, as appropriate).
Definition: variable.hpp:209
const config::attribute value_type
Definition: variable.hpp:111
const config & data_
Definition: variable.hpp:251
const std::string & name() const
Definition: variable.hpp:234
bool memory_managed() const
Returns true if *this has made a copy of its config.
Definition: variable.hpp:203
bool activated() const
Definition: variable.hpp:237
boost::iterator_range< attribute_iterator > attribute_range()
Definition: variable.hpp:138
boost::iterator_range< const_attribute_iterator > const_attr_itors
Definition: config.hpp:286
std::shared_ptr< const config > cache_
Keeps a copy of our config alive when we manage our own memory.
Definition: variable.hpp:207
Encapsulates the map of the game.
Definition: location.hpp:42
attribute_iterator & operator--()
Definition: variable.hpp:124
attribute_iterator operator--(int)
Definition: variable.hpp:125
std::size_t i
Definition: function.cpp:933
mock_party p
bool operator==(const config &a, const config &b)
Definition: config.cpp:1418
static tcache cache
Definition: minimap.cpp:134
scoped_weapon_info(const std::string &var_name, const config &data)
Definition: variable.hpp:247
const config & get_child(const std::string &key)
Definition: general.cpp:216
attribute_iterator & operator++()
Definition: variable.hpp:121
bool operator!=(const attribute_iterator &i) const
Definition: variable.hpp:131
const std::string player_
Definition: variable.hpp:273
scoped_xy_unit(const std::string &var_name, map_location loc, const unit_map &umap)
Definition: variable.hpp:257
Information on a WML variable.
const pointer_proxy pointer
Definition: variable.hpp:116
const std::pair< std::string, vconfig > value_type
Definition: variable.hpp:145
bool operator==(const attribute_iterator &i) const
Definition: variable.hpp:130
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:82
const variable_set * variables_
Definition: variable.hpp:135
Container associating units to locations.
Definition: map.hpp:99
const variable_set * variables_
Definition: variable.hpp:210
attribute_iterator operator++(int)
Definition: variable.hpp:122
static const config default_empty_config
Definition: variable.hpp:211
bool operator!=(const all_children_iterator &i) const
Definition: variable.hpp:169
attribute_iterator(const Itor &i, const variable_set &vars)
Definition: variable.hpp:119
std::vector< vconfig > child_list
Definition: variable.hpp:85
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:68
bool null() const
Definition: variable.hpp:80
const std::string var_name_
Definition: variable.hpp:240
bool empty() const
Definition: config.cpp:884
const value_type reference
Definition: variable.hpp:151
boost::iterator_range< all_children_iterator > all_ordered() const
Definition: variable.hpp:197
const unit_map & umap_
Definition: variable.hpp:262
config_variable_set(const config &cfg)
Definition: variable.hpp:30