The Battle for Wesnoth  1.13.10+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 - 2017 by David White <dave@whitevine.net>
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 #pragma once
16 
18 
19 #include <map>
20 #include <vector>
21 
22 namespace wfl
23 {
24 class formula_callable;
25 class variant_iterator;
26 
27 class variant
28 {
29 public:
31 
32  variant();
33  explicit variant(int n);
34  variant(int n, DECIMAL_VARIANT_TYPE /*type*/);
35  variant(double n, DECIMAL_VARIANT_TYPE /*type*/);
36  explicit variant(const std::vector<variant>& array);
37  explicit variant(const std::string& str);
38  explicit variant(const std::map<variant, variant>& map);
39 
40  template<typename T>
41  variant(std::shared_ptr<T> callable)
42  : value_(std::make_shared<variant_callable>(callable))
43  {
44  assert(value_.get());
45  }
46 
47  variant& operator=(const variant& v);
48 
49  variant operator[](size_t n) const;
50  variant operator[](const variant& v) const;
51 
52  size_t num_elements() const;
53  bool is_empty() const;
54 
55  variant get_member(const std::string& name) const;
56 
57  /** Functions to test the type of the internal value. */
58  bool is_null() const { return type() == VARIANT_TYPE::TYPE_NULL; }
59  bool is_int() const { return type() == VARIANT_TYPE::TYPE_INT; }
60  bool is_decimal() const { return type() == VARIANT_TYPE::TYPE_DECIMAL; }
61  bool is_callable() const { return type() == VARIANT_TYPE::TYPE_CALLABLE; }
62  bool is_list() const { return type() == VARIANT_TYPE::TYPE_LIST; }
63  bool is_string() const { return type() == VARIANT_TYPE::TYPE_STRING; }
64  bool is_map() const { return type() == VARIANT_TYPE::TYPE_MAP; }
65 
66  int as_int() const;
67 
68  /** Returns variant's internal representation of decimal number: ie, 1.234 is represented as 1234 */
69  int as_decimal() const;
70 
71  /** Returns a boolean state of the variant value. The implementation is type-dependent. */
72  bool as_bool() const;
73 
74  const std::vector<variant>& as_list() const;
75  const std::map<variant, variant>& as_map() const;
76 
77  const std::string& as_string() const;
78 
80  {
81  must_be(VARIANT_TYPE::TYPE_CALLABLE);
82  return value_cast<variant_callable>()->get_callable();
83  }
84 
85  template<typename T>
86  std::shared_ptr<T> try_convert() const
87  {
88  if(!is_callable()) {
89  return nullptr;
90  }
91 
92  return std::dynamic_pointer_cast<T>(std::const_pointer_cast<formula_callable>(as_callable()));
93  }
94 
95  template<typename T>
96  std::shared_ptr<T> convert_to() const
97  {
98  std::shared_ptr<T> res = std::dynamic_pointer_cast<T>(std::const_pointer_cast<formula_callable>(as_callable()));
99  if(!res) {
100  throw type_error("could not convert type");
101  }
102 
103  return res;
104  }
105 
106  variant operator+(const variant&) const;
107  variant operator-(const variant&) const;
108  variant operator*(const variant&) const;
109  variant operator/(const variant&) const;
110  variant operator^(const variant&) const;
111  variant operator%(const variant&) const;
112  variant operator-() const;
113 
114  bool operator==(const variant&) const;
115  bool operator!=(const variant&) const;
116  bool operator<(const variant&) const;
117  bool operator>(const variant&) const;
118  bool operator<=(const variant&) const;
119  bool operator>=(const variant&) const;
120 
121  variant list_elements_add(const variant& v) const;
122  variant list_elements_sub(const variant& v) const;
123  variant list_elements_mul(const variant& v) const;
124  variant list_elements_div(const variant& v) const;
125  variant concatenate(const variant& v) const;
126  variant build_range(const variant& v) const;
127 
128  bool contains(const variant& other) const;
129 
130  variant get_keys() const;
131  variant get_values() const;
132 
133  variant_iterator begin() const;
134  variant_iterator end() const;
135 
137  void serialize_from_string(const std::string& str);
138 
139  std::string string_cast() const;
140 
141  std::string to_debug_string(bool verbose = false, formula_seen_stack* seen = nullptr) const;
142 
143  /** Gets string name of the current value type */
145  {
146  return type().to_string();
147  }
148 
149  variant execute_variant(const variant& to_exec);
150 
151 private:
152  template<typename T>
153  std::shared_ptr<T> value_cast() const
154  {
155  return wfl::value_cast<T>(value_);
156  }
157 
158  void must_be(VARIANT_TYPE t) const;
159 
160  void must_both_be(VARIANT_TYPE t, const variant& second) const;
161 
162  VARIANT_TYPE type() const
163  {
164  return value_->get_type();
165  }
166 
167  /**
168  * Variant value.
169  * Each of the constructors initialized this with the appropriate helper class.
170  */
172 };
173 
174 /**
175  * Iterator class for the variant.
176  *
177  * Depending on the @p type_ the @p list_iterator_ and the @p map_iterator_ are
178  * a valid iterator or singular. Since most actions on singular iterators
179  * result in Undefined Behavior care should be taken when copying the
180  * @p list_iterator_ and @p map_iterator_.
181  */
183 {
184 public:
186  typedef std::bidirectional_iterator_tag iterator_category;
187  typedef variant& reference;
188  typedef variant* pointer;
189  typedef int difference_type;
190 
191  /**
192  * Constructor for a no-op iterator.
193  */
195 
196  /**
197  * Constructor for a generic iterator.
198  *
199  * @pre @p iter is not singular.
200  *
201  * @param value A pointer to a variant value representing the container.
202  * @param iter An underlying iterator for the underlying container.
203  */
204  variant_iterator(const variant_value_base* value, const boost::any& iter);
205 
206  variant operator*() const;
211  bool operator==(const variant_iterator& that) const;
212  bool operator!=(const variant_iterator& that) const;
213 private:
214  VARIANT_TYPE type_;
216  boost::any iter_;
217 };
218 
219 }
variant execute_variant(const variant &to_exec)
Definition: variant.cpp:659
bool is_int() const
Definition: variant.hpp:59
const_formula_callable_ptr as_callable() const
Definition: variant.hpp:79
std::vector< char_t > string
void must_be(VARIANT_TYPE t) const
Definition: variant.cpp:613
bool operator<=(const variant &) const
Definition: variant.cpp:533
variant operator%(const variant &) const
Definition: variant.cpp:447
std::shared_ptr< variant_value_base > value_base_ptr
DECIMAL_VARIANT_TYPE
Definition: variant.hpp:30
bool operator>=(const variant &) const
Definition: variant.cpp:528
value_base_ptr value_
Variant value.
Definition: variant.hpp:171
int as_int() const
Definition: variant.cpp:298
variant list_elements_div(const variant &v) const
Definition: variant.cpp:561
variant & operator=(const variant &v)
Definition: variant.cpp:183
std::shared_ptr< T > value_cast() const
Definition: variant.hpp:153
bool operator!=(const variant &) const
Definition: variant.cpp:506
const std::vector< variant > & as_list() const
Definition: variant.cpp:331
STL namespace.
variant_iterator end() const
Definition: variant.cpp:266
static std::shared_ptr< T > value_cast(value_base_ptr ptr)
Casts a variant_value_base shared pointer to a new derived type.
bool operator==(const variant_iterator &that) const
Definition: variant.cpp:124
variant_iterator & operator++()
Definition: variant.cpp:86
variant get_member(const std::string &name) const
Definition: variant.cpp:285
VARIANT_TYPE type() const
Definition: variant.hpp:162
bool contains(const variant &other) const
Definition: variant.cpp:600
bool as_bool() const
Returns a boolean state of the variant value.
Definition: variant.cpp:320
variant(std::shared_ptr< T > callable)
Definition: variant.hpp:41
std::shared_ptr< T > try_convert() const
Definition: variant.hpp:86
bool is_callable() const
Definition: variant.hpp:61
variant_iterator & operator--()
Definition: variant.cpp:105
void serialize_from_string(const std::string &str)
Definition: variant.cpp:635
variant list_elements_sub(const variant &v) const
Definition: variant.cpp:549
VARIANT_TYPE type_
Definition: variant.hpp:214
variant operator^(const variant &) const
Definition: variant.cpp:468
variant operator[](size_t n) const
Definition: variant.cpp:189
variant operator+(const variant &) const
Definition: variant.cpp:343
bool operator>(const variant &) const
Definition: variant.cpp:538
std::string string_cast() const
Definition: variant.cpp:644
std::bidirectional_iterator_tag iterator_category
Definition: variant.hpp:186
bool is_empty() const
Definition: variant.cpp:271
variant operator*() const
Definition: variant.cpp:77
int as_decimal() const
Returns variant's internal representation of decimal number: ie, 1.234 is represented as 1234...
Definition: variant.cpp:307
const std::map< variant, variant > & as_map() const
Definition: variant.cpp:337
variant get_keys() const
Definition: variant.cpp:237
variant build_range(const variant &v) const
Definition: variant.cpp:593
std::vector< const_formula_callable_ptr > formula_seen_stack
std::shared_ptr< const formula_callable > const_formula_callable_ptr
const variant_value_base * container_
Definition: variant.hpp:215
bool is_list() const
Definition: variant.hpp:62
bool is_null() const
Functions to test the type of the internal value.
Definition: variant.hpp:58
variant operator/(const variant &) const
Definition: variant.cpp:412
void must_both_be(VARIANT_TYPE t, const variant &second) const
Definition: variant.cpp:620
bool operator==(const variant &) const
Definition: variant.cpp:493
std::string type_string() const
Gets string name of the current value type.
Definition: variant.hpp:144
bool is_map() const
Definition: variant.hpp:64
double t
Definition: astarsearch.cpp:64
Definition: contexts.hpp:42
variant operator*(const variant &) const
Definition: variant.cpp:389
size_t num_elements() const
Definition: variant.cpp:276
bool is_string() const
Definition: variant.hpp:63
std::string to_debug_string(bool verbose=false, formula_seen_stack *seen=nullptr) const
Definition: variant.cpp:649
bool is_decimal() const
Definition: variant.hpp:60
variant concatenate(const variant &v) const
Definition: variant.cpp:567
Base class for all variant types.
static const char * name(const std::vector< SDL_Joystick * > &joysticks, const size_t index)
Definition: joystick.cpp:48
variant_iterator begin() const
Definition: variant.cpp:261
variant_iterator()
Constructor for a no-op iterator.
Definition: variant.cpp:63
bool operator!=(const variant_iterator &that) const
Definition: variant.cpp:137
const std::string & as_string() const
Definition: variant.cpp:325
std::string serialize_to_string() const
Definition: variant.cpp:630
std::shared_ptr< T > convert_to() const
Definition: variant.hpp:96
variant list_elements_mul(const variant &v) const
Definition: variant.cpp:555
Iterator class for the variant.
Definition: variant.hpp:182
variant get_values() const
Definition: variant.cpp:249
static map_location::DIRECTION n
variant list_elements_add(const variant &v) const
Definition: variant.cpp:543
variant operator-() const
Definition: variant.cpp:484
bool operator<(const variant &) const
Definition: variant.cpp:511