The Battle for Wesnoth  1.19.22+dev
variant.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2025
3  by David White <dave@whitevine.net>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #pragma once
17 
18 #include "exceptions.hpp"
19 #include "formula/callable_fwd.hpp"
21 
22 #include "utils/any.hpp"
23 #include <map>
24 #include <vector>
25 
26 namespace wfl
27 {
28 class formula_callable;
29 class variant;
30 class variant_value_base;
31 class variant_iterator;
32 
33 struct type_error : public game::error
34 {
35  explicit type_error(const std::string& str);
36 };
37 
38 class variant
39 {
40 public:
42 
43  variant();
44  explicit variant(int n);
45  variant(int n, DECIMAL_VARIANT_TYPE /*type*/);
46  variant(double n, DECIMAL_VARIANT_TYPE /*type*/);
47  explicit variant(const std::vector<variant>& array);
48  explicit variant(std::vector<variant>&& array);
49  explicit variant(const std::string& str);
50  explicit variant(std::string&& str);
51  explicit variant(const std::map<variant, variant>& map);
52  explicit variant(std::map<variant, variant>&& map);
53  explicit variant(const_formula_callable_ptr callable);
54  variant(const variant& v) = default;
55  variant(variant&& v) = default;
56 
57  variant& operator=(const variant& v) = default;
58  variant& operator=(variant&& v) = default;
59 
60  variant operator[](std::size_t n) const;
61  variant operator[](const variant& v) const;
62 
63  std::size_t num_elements() const;
64  bool is_empty() const;
65 
66  variant get_member(const std::string& name) const;
67 
68  /** Functions to test the type of the internal value. */
69  bool is_null() const { return type() == formula_variant::type::null; }
70  bool is_int() const { return type() == formula_variant::type::integer; }
71  bool is_decimal() const { return type() == formula_variant::type::decimal; }
72  bool is_callable() const { return type() == formula_variant::type::object; }
73  bool is_list() const { return type() == formula_variant::type::list; }
74  bool is_string() const { return type() == formula_variant::type::string; }
75  bool is_map() const { return type() == formula_variant::type::map; }
76 
77  /**
78  * Returns the variant's value as an integer.
79  * If @ref is_null() is true, returns @a fallback.
80  */
81  int as_int(int fallback = 0) const;
82 
83  /**
84  * Returns the variant's internal representation of decimal number: ie, 1.234 is represented as 1234.
85  * If @ref is_null() is true, returns @a fallback.
86  */
87  int as_decimal(int fallback = 0) const;
88 
89  /** Returns a boolean state of the variant value. The implementation is type-dependent. */
90  bool as_bool() const;
91 
92  const std::vector<variant>& as_list() const;
93  const std::map<variant, variant>& as_map() const;
94 
95  const std::string& as_string() const;
96 
98 
99  variant operator+(const variant&) const;
100  variant operator-(const variant&) const;
101  variant operator*(const variant&) const;
102  variant operator/(const variant&) const;
103  variant operator^(const variant&) const;
104  variant operator%(const variant&) const;
105  variant operator-() const;
106 
107  bool operator==(const variant&) const;
108  bool operator!=(const variant&) const;
109  bool operator<(const variant&) const;
110  bool operator>(const variant&) const;
111  bool operator<=(const variant&) const;
112  bool operator>=(const variant&) const;
113 
114  variant list_elements_add(const variant& v) const;
115  variant list_elements_sub(const variant& v) const;
116  variant list_elements_mul(const variant& v) const;
117  variant list_elements_div(const variant& v) const;
118  variant concatenate(const variant& v) const;
119  variant build_range(const variant& v) const;
120 
121  bool contains(const variant& other) const;
122 
123  variant get_keys() const;
124  variant get_values() const;
125 
126  variant_iterator begin() const;
127  variant_iterator end() const;
128 
129  std::string serialize_to_string() const;
130  void serialize_from_string(const std::string& str);
131 
132  std::string string_cast() const;
133 
134  std::string to_debug_string(bool verbose = false, formula_seen_stack* seen = nullptr) const;
135 
136  formula_variant::type type() const;
137 
138 private:
139  template<typename T>
140  friend std::shared_ptr<T> value_cast(const variant& v);
141 
142  /** @invariant Never null. */
143  std::shared_ptr<variant_value_base> value_;
144 };
145 
146 /**
147  * Executes all action_callables in @a execute using the provided context.
148  */
149 variant execute_actions(const variant& execute, const variant& context);
150 
151 /**
152  * Iterator class for the variant.
153  *
154  * Depending on the @p type_ the @p list_iterator_ and the @p map_iterator_ are
155  * a valid iterator or singular. Since most actions on singular iterators
156  * result in Undefined Behavior care should be taken when copying the
157  * @p list_iterator_ and @p map_iterator_.
158  */
160 {
161 public:
163  typedef std::bidirectional_iterator_tag iterator_category;
164  typedef variant& reference;
165  typedef variant* pointer;
166  typedef int difference_type;
167 
168  /**
169  * Constructor for a no-op iterator.
170  */
172 
173  /**
174  * Constructor for a generic iterator.
175  *
176  * @pre @p iter is not singular.
177  *
178  * @param value A pointer to a variant value representing the container.
179  * @param iter An underlying iterator for the underlying container.
180  */
181  variant_iterator(const variant_value_base* value, const utils::any& iter);
182 
183  variant operator*() const;
188  bool operator==(const variant_iterator& that) const;
189  bool operator!=(const variant_iterator& that) const;
190 private:
193  utils::any iter_;
194 };
195 
196 }
MacOS doesn't support std::any_cast when targing MacOS < 10.14 (currently we target 10....
Iterator class for the variant.
Definition: variant.hpp:160
bool operator!=(const variant_iterator &that) const
Definition: variant.cpp:166
const variant_value_base * container_
Definition: variant.hpp:192
variant operator*() const
Definition: variant.cpp:106
bool operator==(const variant_iterator &that) const
Definition: variant.cpp:153
variant_iterator & operator--()
Definition: variant.cpp:134
std::bidirectional_iterator_tag iterator_category
Definition: variant.hpp:163
formula_variant::type type_
Definition: variant.hpp:191
variant_iterator()
Constructor for a no-op iterator.
Definition: variant.cpp:92
variant_iterator & operator++()
Definition: variant.cpp:115
Base class for all variant types.
variant operator-() const
Definition: variant.cpp:509
bool is_map() const
Definition: variant.hpp:75
bool is_list() const
Definition: variant.hpp:73
variant operator^(const variant &) const
Definition: variant.cpp:493
variant concatenate(const variant &v) const
Definition: variant.cpp:635
variant get_keys() const
Definition: variant.cpp:277
variant_iterator begin() const
Definition: variant.cpp:297
variant & operator=(const variant &v)=default
std::shared_ptr< variant_value_base > value_
Definition: variant.hpp:143
int as_int(int fallback=0) const
Returns the variant's value as an integer.
Definition: variant.cpp:336
variant operator/(const variant &) const
Definition: variant.cpp:437
variant get_values() const
Definition: variant.cpp:287
friend std::shared_ptr< T > value_cast(const variant &v)
Definition: variant.cpp:77
void serialize_from_string(const std::string &str)
Definition: variant.cpp:671
int as_decimal(int fallback=0) const
Returns the variant's internal representation of decimal number: ie, 1.234 is represented as 1234.
Definition: variant.cpp:344
const_formula_callable_ptr as_callable() const
Definition: variant.cpp:377
bool operator>=(const variant &) const
Definition: variant.cpp:553
variant(variant &&v)=default
std::size_t num_elements() const
Definition: variant.cpp:312
DECIMAL_VARIANT_TYPE
Definition: variant.hpp:41
@ DECIMAL_VARIANT
Definition: variant.hpp:41
formula_variant::type type() const
Definition: variant.cpp:226
variant(const variant &v)=default
bool is_decimal() const
Definition: variant.hpp:71
bool operator!=(const variant &) const
Definition: variant.cpp:531
variant operator+(const variant &) const
Definition: variant.cpp:382
bool is_empty() const
Definition: variant.cpp:307
bool contains(const variant &other) const
Definition: variant.cpp:654
bool operator==(const variant &) const
Definition: variant.cpp:518
bool operator>(const variant &) const
Definition: variant.cpp:563
variant operator*(const variant &) const
Definition: variant.cpp:414
variant get_member(const std::string &name) const
Definition: variant.cpp:321
variant list_elements_mul(const variant &v) const
Definition: variant.cpp:625
std::string serialize_to_string() const
Definition: variant.cpp:666
variant list_elements_add(const variant &v) const
Definition: variant.cpp:615
const std::string & as_string() const
Definition: variant.cpp:362
std::string string_cast() const
Definition: variant.cpp:681
variant list_elements_div(const variant &v) const
Definition: variant.cpp:630
variant_iterator end() const
Definition: variant.cpp:302
bool as_bool() const
Returns a boolean state of the variant value.
Definition: variant.cpp:357
bool operator<(const variant &) const
Definition: variant.cpp:536
variant & operator=(variant &&v)=default
variant operator[](std::size_t n) const
Definition: variant.cpp:231
bool is_string() const
Definition: variant.hpp:74
variant build_range(const variant &v) const
Definition: variant.cpp:648
bool is_callable() const
Definition: variant.hpp:72
variant operator%(const variant &) const
Definition: variant.cpp:472
const std::vector< variant > & as_list() const
Definition: variant.cpp:367
bool operator<=(const variant &) const
Definition: variant.cpp:558
std::string to_debug_string(bool verbose=false, formula_seen_stack *seen=nullptr) const
Definition: variant.cpp:686
const std::map< variant, variant > & as_map() const
Definition: variant.cpp:372
bool is_null() const
Functions to test the type of the internal value.
Definition: variant.hpp:69
bool is_int() const
Definition: variant.hpp:70
variant list_elements_sub(const variant &v) const
Definition: variant.cpp:620
Definition: callable.hpp:26
std::vector< const_formula_callable_ptr > formula_seen_stack
std::shared_ptr< const formula_callable > const_formula_callable_ptr
variant execute_actions(const variant &execute, const variant &context)
Executes all action_callables in execute using the provided context.
Definition: variant.cpp:696
Base class for all the errors encountered by the engine.
Definition: exceptions.hpp:29
type_error(const std::string &str)
Definition: variant.cpp:87
static map_location::direction n