The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
variant.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2016 by David White <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #ifndef VARIANT_HPP_INCLUDED
16 #define VARIANT_HPP_INCLUDED
17 
18 #include <boost/shared_ptr.hpp>
19 #include <map>
20 #include <vector>
21 
22 #include "exceptions.hpp"
23 
24 namespace game_logic {
25 class formula_callable;
26 }
27 
28 void push_call_stack(const char* str);
29 void pop_call_stack();
31 
33  explicit call_stack_manager(const char* str) {
34  push_call_stack(str);
35  }
36 
39  }
40 };
41 
42 struct variant_list;
43 struct variant_string;
44 struct variant_map;
45 class variant_iterator;
46 
47 struct type_error : public game::error {
48  explicit type_error(const std::string& str);
49 };
50 
51 
52 class variant {
53 public:
54 
56 
58 
59  variant();
60  explicit variant(int n);
61  variant(int n, DECIMAL_VARIANT_TYPE /*type*/);
62  variant(double n, DECIMAL_VARIANT_TYPE /*type*/);
63  explicit variant(const game_logic::formula_callable* callable);
64  explicit variant(std::vector<variant>* array);
65  explicit variant(const std::string& str);
66  explicit variant(std::map<variant,variant>* map);
67  ~variant();
68 
69  variant(const variant& v);
70  variant& operator=(const variant& v);
71 
72  variant operator[](size_t n) const;
73  variant operator[](const variant& v) const;
74  size_t num_elements() const;
75  bool is_empty() const;
76 
77  variant get_member(const std::string& str) const;
78 
79  bool is_string() const { return type_ == TYPE_STRING; }
80  bool is_null() const { return type_ == TYPE_NULL; }
81  bool is_int() const { return type_ == TYPE_INT; }
82  bool is_decimal() const { return type_ == TYPE_DECIMAL; }
83  bool is_map() const { return type_ == TYPE_MAP; }
84  int as_int() const;
85 
86  //this function returns variant's internal representation of decimal number:
87  //for example number 1.234 is represented as 1234
88  int as_decimal() const;
89 
90  bool as_bool() const;
91 
92  bool is_list() const { return type_ == TYPE_LIST; }
93 
94  const std::vector<variant>& as_list() const;
95  const std::map<variant,variant>& as_map() const;
96 
97  const std::string& as_string() const;
98  std::string type_string() const;
99 
100  bool is_callable() const { return type_ == TYPE_CALLABLE; }
102  must_be(TYPE_CALLABLE); return callable_; }
105 
106  template<typename T>
107  T* try_convert() const {
108  if(!is_callable()) {
109  return nullptr;
110  }
111 
112  return dynamic_cast<T*>(mutable_callable());
113  }
114 
115  template<typename T>
116  T* convert_to() const {
117  T* res = dynamic_cast<T*>(mutable_callable());
118  if(!res) {
119  throw type_error("could not convert type");
120  }
121 
122  return res;
123  }
124 
125  variant operator+(const variant&) const;
126  variant operator-(const variant&) const;
127  variant operator*(const variant&) const;
128  variant operator/(const variant&) const;
129  variant operator^(const variant&) const;
130  variant operator%(const variant&) const;
131  variant operator-() const;
132 
133  bool operator==(const variant&) const;
134  bool operator!=(const variant&) const;
135  bool operator<(const variant&) const;
136  bool operator>(const variant&) const;
137  bool operator<=(const variant&) const;
138  bool operator>=(const variant&) const;
139 
140  variant list_elements_add(const variant& v) const;
141  variant list_elements_sub(const variant& v) const;
142  variant list_elements_mul(const variant& v) const;
143  variant list_elements_div(const variant& v) const;
144  variant concatenate(const variant& v) const;
145  variant build_range(const variant& v) const;
146  bool contains(const variant& other) const;
147 
148  variant get_keys() const;
149  variant get_values() const;
150 
151  variant_iterator begin() const;
152  variant_iterator end() const;
153 
154  void serialize_to_string(std::string& str) const;
155  void serialize_from_string(const std::string& str);
156 
157  int refcount() const;
158 
159  std::string string_cast() const;
160 
161  std::string to_debug_string(std::vector<const game_logic::formula_callable*>* seen=nullptr, bool verbose = false) const;
162 
163 private:
164  void must_be(TYPE t) const;
166  union {
174  };
175 
176  void increment_refcount();
177  void release();
178 };
179 
180 /**
181  * Iterator class for the variant.
182  *
183  * Depending on the @p type_ the @p list_iterator_ and the @p map_iterator_ are
184  * a valid iterator or singular. Since most actions on singular iterators
185  * result in Undefined Behavior care should be taken when copying the
186  * @p list_iterator_ and @p map_iterator_.
187  */
189 public:
191  typedef std::bidirectional_iterator_tag iterator_category;
192  typedef variant& reference;
193  typedef variant* pointer;
194  typedef int difference_type;
195 
196  /**
197  * Constructor for a TYPE_NULL variant.
198  */
200 
201  /**
202  * Constructor for a TYPE_LIST variant.
203  *
204  * @pre @p iter is not singular.
205  *
206  * @param iter Iterator to initialize @p list_iterator_ with.
207  */
208  explicit variant_iterator(const std::vector<variant>::iterator& iter);
209 
210  /**
211  * Constructor for a TYPE_MAP variant.
212  *
213  * @pre @p iter is not singular.
214  *
215  * @param iter Iterator to initialize @p map_iterator_ with.
216  */
218 
220 
221  variant operator*() const;
227  bool operator==(const variant_iterator& that) const;
228  bool operator!=(const variant_iterator& that) const;
229 
231 private:
235 };
236 
237 template<typename T>
239  T* res = dynamic_cast<T*>(v.mutable_callable());
240  if(!res) {
241  throw type_error("could not convert type");
242  }
243 
244  return res;
245 }
246 
247 
248 template<typename T>
250  if(!v.is_callable()) {
251  return nullptr;
252  }
253 
254  return dynamic_cast<T*>(v.mutable_callable());
255 }
256 
257 
258 
259 #endif
bool operator<(const variant &) const
Definition: variant.cpp:889
size_t num_elements() const
Definition: variant.cpp:526
variant value_type
Definition: variant.hpp:190
variant operator^(const variant &) const
Definition: variant.cpp:748
variant operator*(const variant &) const
Definition: variant.cpp:670
variant build_range(const variant &v) const
Definition: variant.cpp:1001
variant operator/(const variant &) const
Definition: variant.cpp:692
bool is_callable() const
Definition: variant.hpp:100
T * convert_to() const
Definition: variant.hpp:116
std::vector< variant >::iterator list_iterator_
Definition: variant.hpp:233
variant & reference
Definition: variant.hpp:192
int decimal_value_
Definition: variant.hpp:168
game_logic::formula_callable * mutable_callable() const
Definition: variant.hpp:103
variant_string * string_
Definition: variant.hpp:172
const game_logic::formula_callable * as_callable() const
Definition: variant.hpp:101
void must_be(TYPE t) const
Definition: variant.cpp:1036
variant_iterator end() const
Definition: variant.cpp:500
const std::map< variant, variant > & as_map() const
Definition: variant.cpp:617
bool contains(const variant &other) const
Definition: variant.cpp:1018
bool is_decimal() const
Definition: variant.hpp:82
variant list_elements_sub(const variant &v) const
Definition: variant.cpp:917
bool as_bool() const
Definition: variant.cpp:580
variant list_elements_mul(const variant &v) const
Definition: variant.cpp:935
const game_logic::formula_callable * callable_
Definition: variant.hpp:169
GLdouble GLdouble t
Definition: glew.h:1366
call_stack_manager(const char *str)
Definition: variant.hpp:33
void push_call_stack(const char *str)
Definition: variant.cpp:54
type_error(const std::string &str)
Definition: variant.cpp:79
bool is_null() const
Definition: variant.hpp:80
bool operator<=(const variant &) const
Definition: variant.cpp:829
variant list_elements_add(const variant &v) const
Definition: variant.cpp:899
game_logic::formula_callable * mutable_callable_
Definition: variant.hpp:170
GLenum array
Definition: glew.h:6910
TYPE type_
Definition: variant.hpp:165
T * try_convert_variant(const variant &v)
Definition: variant.hpp:249
bool is_list() const
Definition: variant.hpp:92
int as_int() const
Definition: variant.cpp:558
const GLdouble * v
Definition: glew.h:1359
variant list_elements_div(const variant &v) const
Definition: variant.cpp:953
bool operator>(const variant &) const
Definition: variant.cpp:894
std::map< variant, variant >::iterator map_iterator_
Definition: variant.hpp:234
std::bidirectional_iterator_tag iterator_category
Definition: variant.hpp:191
std::string string_cast() const
Definition: variant.cpp:1165
Iterator class for the variant.
Definition: variant.hpp:188
variant get_keys() const
Definition: variant.cpp:468
void serialize_to_string(std::string &str) const
Definition: variant.cpp:1045
variant operator*() const
Definition: variant.cpp:126
variant * pointer
Definition: variant.hpp:193
variant concatenate(const variant &v) const
Definition: variant.cpp:971
int int_value_
Definition: variant.hpp:167
bool is_empty() const
Definition: variant.cpp:511
GLuint res
Definition: glew.h:9258
variant_iterator begin() const
Definition: variant.cpp:490
int as_decimal() const
Definition: variant.cpp:565
bool is_map() const
Definition: variant.hpp:83
std::string get_call_stack()
Definition: variant.cpp:64
variant_map * map_
Definition: variant.hpp:173
variant & operator=(const variant &v)
Definition: variant.cpp:409
const std::string & as_string() const
Definition: variant.cpp:603
bool operator==(const variant &) const
Definition: variant.cpp:771
void pop_call_stack()
Definition: variant.cpp:59
variant_iterator & operator--()
Definition: variant.cpp:167
variant_list * list_
Definition: variant.hpp:171
variant operator%(const variant &) const
Definition: variant.cpp:726
variant operator+(const variant &) const
Definition: variant.cpp:624
bool operator!=(const variant_iterator &that) const
Definition: variant.cpp:234
void release()
Definition: variant.cpp:309
void increment_refcount()
Definition: variant.cpp:285
variant()
Definition: variant.cpp:343
T * try_convert() const
Definition: variant.hpp:107
variant_iterator()
Constructor for a TYPE_NULL variant.
Definition: variant.cpp:83
DECIMAL_VARIANT_TYPE
Definition: variant.hpp:57
std::string to_debug_string(std::vector< const game_logic::formula_callable * > *seen=nullptr, bool verbose=false) const
Definition: variant.cpp:1229
GLclampd n
Definition: glew.h:5903
Base class for all the errors encountered by the engine.
Definition: exceptions.hpp:27
variant get_values() const
Definition: variant.cpp:479
const std::vector< variant > & as_list() const
Definition: variant.cpp:610
variant get_member(const std::string &str) const
Definition: variant.cpp:545
void serialize_from_string(const std::string &str)
Definition: variant.cpp:1136
variant operator-() const
Definition: variant.cpp:763
bool is_string() const
Definition: variant.hpp:79
variant_iterator & operator=(const variant_iterator &that)
Definition: variant.cpp:194
std::string::const_iterator iterator
Definition: tokenizer.hpp:21
variant_iterator & operator++()
Definition: variant.cpp:140
GLsizei const GLcharARB ** string
Definition: glew.h:4503
variant operator[](size_t n) const
Definition: variant.cpp:419
T * convert_variant(const variant &v)
Definition: variant.hpp:238
std::string type_string() const
Definition: variant.cpp:339
~variant()
Definition: variant.cpp:404
bool is_int() const
Definition: variant.hpp:81
bool operator>=(const variant &) const
Definition: variant.cpp:884
int refcount() const
Definition: variant.cpp:1145
bool operator!=(const variant &) const
Definition: variant.cpp:824
bool operator==(const variant_iterator &that) const
Definition: variant.cpp:216