The Battle for Wesnoth  1.15.2+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 
22 #include <utility>
23 
24 class unit_map;
25 
27  const config& cfg_;
28 public:
29  config_variable_set(const config& cfg) : cfg_(cfg) {}
30  virtual config::attribute_value get_variable_const(const std::string &id) const;
31 };
32 
33 /**
34  * A variable-expanding proxy for the config class. This class roughly behaves
35  * as a constant config object, but automatically expands variables.
36  *
37  * When dealing with a vconfig, keep in mind its lifetime. By default, vconfigs
38  * do not maintain a copy their data; if you need a vconfig to stick around,
39  * either construct it with manage_memory=true or call make_safe(). This will
40  * cause the vconfig to make a copy of the underlying config object.
41  */
42 class vconfig
43 {
44 private:
45 
46 /*
47  * Starting with the rc of gcc 4.6 the code failed to compile due to the
48  * missing default constructor for vconfig. Not entirely sure whether it's a
49  * bug in gcc or not. For now make the code conditional.
50  */
51 #if __GNUC__ == 4 && __GNUC_MINOR__ == 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
52  template<class T1, class T2>
53  friend class std::pair;
54 #endif
55 
56  vconfig();
57  vconfig(const config & cfg, const std::shared_ptr<const config> & cache);
58 public:
59  /// Constructor from a config.
60  /// Equivalent to vconfig(cfg, false).
61  /// Do not use if the vconfig will persist after @a cfg is destroyed!
62  explicit vconfig(const config &cfg) : cache_(), cfg_(&cfg) {}
63  explicit vconfig(config &&cfg) : cache_(new config(std::move(cfg))), cfg_(cache_.get()) { }
64  vconfig(const config &cfg, bool manage_memory);
65  ~vconfig();
66 
67  static vconfig empty_vconfig(); // Valid to dereference. Contains nothing
68  static vconfig unconstructed_vconfig(); // Must not be dereferenced
69 
70  /// A vconfig evaluates to true iff it can be dereferenced.
71  explicit operator bool() const { return !null(); }
72 
73  bool null() const { assert(cfg_); return cfg_ == &default_empty_config; }
74  const vconfig& make_safe() const; //!< instruct the vconfig to make a private copy of its underlying data.
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): i_(i) {}
113 
114  attribute_iterator &operator++() { ++i_; return *this; }
116 
117  attribute_iterator &operator--() { --i_; return *this; }
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_;
128  };
129 
130  boost::iterator_range<attribute_iterator> attribute_range() {
132  return boost::make_iterator_range(attribute_iterator(range.begin()), attribute_iterator(range.end()));
133  }
134 
136  {
138 
139  typedef const std::pair<std::string, vconfig> value_type;
140  typedef std::bidirectional_iterator_tag iterator_category;
141  typedef int difference_type;
142  typedef const pointer_proxy pointer;
143  typedef const value_type reference;
145  explicit all_children_iterator(const Itor &i);
146  all_children_iterator(const Itor &i, const std::shared_ptr<const config> & cache);
147 
148  all_children_iterator& operator++();
149  all_children_iterator operator++(int);
150  all_children_iterator& operator--();
151  all_children_iterator operator--(int);
152 
153  reference operator*() const;
154  pointer operator->() const;
155 
156  std::string get_key() const;
157  vconfig get_child() const;
158  void disable_insertion() { inner_index_ = -1; }
159 
160  bool operator==(const all_children_iterator &i) const;
161  bool operator!=(const all_children_iterator &i) const
162  { return !operator==(i); }
163 
164  private:
165  Itor i_;
166  /*
167  if wa have game variables
168  [a] b = 1 [/a]
169  [a] b = 4 [/a]
170  [a] b = 6 [/a]
171  we want to expand [insert_tag] variable = a name = "u" [/insert_tag] to
172  [u] b = 1 [/u]
173  [u] b = 4 [/u]
174  [u] b = 6 [/u]
175  in this case inner_index_ points to the index in 'a' we are currently processing.
176  */
178  std::shared_ptr<const config> cache_;
179  };
180 
181  struct recursion_error : public config::error {
182  recursion_error(const std::string& msg) : error(msg) {}
183  };
184 
185  /** In-order iteration over all children. */
186  all_children_iterator ordered_begin() const;
187  all_children_iterator ordered_end() const;
188  boost::iterator_range<all_children_iterator> all_ordered() const {
189  return boost::make_iterator_range(ordered_begin(), ordered_end());
190  }
191 
192 private:
193  /// Returns true if *this has made a copy of its config.
194  bool memory_managed() const { return static_cast<bool>(cache_); }
195 
196  /// Keeps a copy of our config alive when we manage our own memory.
197  /// If this is not null, then cfg_ points to *cache_ or a child of *cache_.
198  mutable std::shared_ptr<const config> cache_;
199  /// Used to access our config (original or copy, as appropriate).
200  mutable const config* cfg_;
202 };
203 
205 {
208  value_type *operator->() const { return &p; }
209 };
210 
212 {
215  value_type *operator->() const { return &p; }
216 };
217 
218 
220 {
221 public:
222  scoped_wml_variable(const std::string& var_name);
223  virtual ~scoped_wml_variable();
224  const std::string& name() const { return var_name_; }
225  virtual void activate() = 0;
226  config &store(const config &var_value = config());
227  bool activated() const { return activated_; }
228 private:
230  const std::string var_name_;
232 };
233 
235 {
236 public:
237  scoped_weapon_info(const std::string& var_name, const config &data)
238  : scoped_wml_variable(var_name), data_(data) {}
239  void activate();
240 private:
241  const config& data_;
242 };
243 
245 {
246 public:
247  scoped_xy_unit(const std::string& var_name, map_location loc, const unit_map& umap)
248  : scoped_wml_variable(var_name), loc_(loc), umap_(umap) {}
249  void activate();
250 private:
252  const unit_map& umap_;
253 };
254 
256 {
257 public:
258  scoped_recall_unit(const std::string& var_name, const std::string& player,
259  unsigned int recall_index) : scoped_wml_variable(var_name), player_(player),
260  recall_index_(recall_index) {}
261  void activate();
262 private:
263  const std::string player_;
264  unsigned int recall_index_;
265 };
recursion_error(const std::string &msg)
Definition: variable.hpp:182
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:58
const map_location loc_
Definition: variable.hpp:251
std::shared_ptr< const config > cache_
Definition: variable.hpp:178
vconfig(const config &cfg)
Constructor from a config.
Definition: variable.hpp:62
config::const_all_children_iterator Itor
Definition: variable.hpp:144
attribute_iterator(const Itor &i)
Definition: variable.hpp:112
Variant for storing WML attributes.
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
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:226
std::bidirectional_iterator_tag iterator_category
Definition: variable.hpp:107
STL namespace.
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:142
scoped_recall_unit(const std::string &var_name, const std::string &player, unsigned int recall_index)
Definition: variable.hpp:258
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:140
const_attr_itors attribute_range() const
Definition: config.cpp:809
unsigned int recall_index_
Definition: variable.hpp:264
map_location loc_
const config * cfg_
Used to access our config (original or copy, as appropriate).
Definition: variable.hpp:200
const config::attribute value_type
Definition: variable.hpp:104
const config & data_
Definition: variable.hpp:241
const std::string & name() const
Definition: variable.hpp:224
bool memory_managed() const
Returns true if *this has made a copy of its config.
Definition: variable.hpp:194
bool activated() const
Definition: variable.hpp:227
boost::iterator_range< attribute_iterator > attribute_range()
Definition: variable.hpp:130
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:198
Encapsulates the map of the game.
Definition: location.hpp:42
attribute_iterator & operator--()
Definition: variable.hpp:117
attribute_iterator operator--(int)
Definition: variable.hpp:118
std::size_t i
Definition: function.cpp:933
mock_party p
bool operator==(const config &a, const config &b)
Definition: config.cpp:1405
static tcache cache
Definition: minimap.cpp:134
CURSOR_TYPE get()
Definition: cursor.cpp:213
scoped_weapon_info(const std::string &var_name, const config &data)
Definition: variable.hpp:237
const config & get_child(const std::string &key)
Definition: general.cpp:215
vconfig(config &&cfg)
Definition: variable.hpp:63
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:263
scoped_xy_unit(const std::string &var_name, map_location loc, const unit_map &umap)
Definition: variable.hpp:247
const pointer_proxy pointer
Definition: variable.hpp:109
const std::pair< std::string, vconfig > value_type
Definition: variable.hpp:137
bool operator==(const attribute_iterator &i) const
Definition: variable.hpp:123
const config & cfg_
Definition: variable.hpp:27
A variable-expanding proxy for the config class.
Definition: variable.hpp:42
const config & get_config() const
Definition: variable.hpp:75
Container associating units to locations.
Definition: map.hpp:99
attribute_iterator operator++(int)
Definition: variable.hpp:115
static const config default_empty_config
Definition: variable.hpp:201
bool operator!=(const all_children_iterator &i) const
Definition: variable.hpp:161
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:68
bool null() const
Definition: variable.hpp:73
const std::string var_name_
Definition: variable.hpp:230
bool empty() const
Definition: config.cpp:884
const value_type reference
Definition: variable.hpp:143
boost::iterator_range< all_children_iterator > all_ordered() const
Definition: variable.hpp:188
const unit_map & umap_
Definition: variable.hpp:252
config_variable_set(const config &cfg)
Definition: variable.hpp:29