The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
variable_info_detail.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2005 - 2025
3 by Philippe Plantier <ayin@anathas.org>
4 Copyright (C) 2003 by David White <dave@whitevine.net>
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 "utils/const_clone.hpp"
21
22#include <string>
23#include <type_traits>
24
26{
27/**
28 * The variable_info policy classes.
29 *
30 * Each of these classes describes a different behavior for reading data from a variable
31 * and should implement two functions:
32 *
33 * - get_child_at Describes the desired behavior when reading variable info.
34 * - error_message Error message regarding policy behavior.
35 */
36
37/** Takes a const reference and is guaranteed to not change the config. */
39{
40public:
41 static const config& get_child_at(const config& cfg, const std::string& key, int index)
42 {
43 assert(index >= 0);
44 // cfg.child_or_empty does not support index parameter
45 if(auto child = cfg.optional_child(key, index)) {
46 return *child;
47 }
48
49 static const config empty_const_cfg;
50 return empty_const_cfg;
51 }
52
53 static std::string error_message(const std::string& name)
54 {
55 return "Cannot resolve variable '" + name + "' for reading.";
56 }
57};
58
59/** Creates a child table when resolving name if it doesn't exist yet. */
61{
62public:
63 static config& get_child_at(config& cfg, const std::string& key, int index)
64 {
65 assert(index >= 0);
66 // the 'create_if_not_existent' logic.
67 while(static_cast<int>(cfg.child_count(key)) <= index) {
68 cfg.add_child(key);
69 }
70
71 return cfg.mandatory_child(key, index);
72 }
73
74 static std::string error_message(const std::string& name)
75 {
76 return "Cannot resolve variable '" + name + "' for writing.";
77 }
78};
79
80/**
81 * Will throw an exception when trying to access a nonexistent table.
82 * Note that the other types can throw too if name is invlid, such as '..[[[a'.
83 */
85{
86public:
87 static config& get_child_at(config& cfg, const std::string& key, int index)
88 {
89 assert(index >= 0);
90 if(auto child = cfg.optional_child(key, index)) {
91 return *child;
92 }
93
95 }
96
97 static std::string error_message(const std::string& name)
98 {
99 return "Cannot resolve variable '" + name + "' for writing without creating new children.";
100 }
101};
102
103// ==================================================================
104// Other implementation details.
105// ==================================================================
106
107template<typename T, typename V>
108struct maybe_const : public utils::const_clone<T, V>
109{
110 // Meta type aliases provided by const_clone
111};
112
113template<>
114struct maybe_const<config::child_itors, const vi_policy_const>
115{
117};
118
120 state_start = 0, /**< Represents the initial variable state before processing. */
121 state_named, /**< The result of .someval. This can either mean an attribute value or a child range. */
122 state_indexed, /**< The result of .someval[index]. This is never an attribute value and is always a single config. */
123 state_temporary, /**< The result of .length. This value can never be written, it can only be read. */
124};
125
126template<typename V>
128{
130
132 : child_(&vars)
133 , key_()
134 , index_(0)
135 , temp_val_()
137 {
138 child_ = &vars;
139 }
140
141 // The meaning of the following 3 depends on 'type_', but the current config is usually
142 // child_->child_at(key_, index_).
144 std::string key_;
146
147 // If we have a temporary value like .length we store the result here.
149
150 // See @ref variable_info_state_type
152};
153} // end namespace variable_info_implementation
154
155/** Helper template alias for maybe_const, defined at global scope for convenience. */
156template<typename T, typename V>
Variant for storing WML attributes.
A config object defines a single node in a WML file, with access to child nodes.
Definition config.hpp:157
config & add_child(std::string_view key)
Definition config.cpp:436
optional_config_impl< config > optional_child(std::string_view key, int n=0)
Equivalent to mandatory_child, but returns an empty optional if the nth child was not found.
Definition config.cpp:380
std::size_t child_count(std::string_view key) const
Definition config.cpp:292
boost::iterator_range< const_child_iterator > const_child_itors
Definition config.hpp:281
config & mandatory_child(std::string_view key, int n=0)
Returns the nth child with the given key, or throws an error if there is none.
Definition config.cpp:362
static std::string error_message(const std::string &name)
static const config & get_child_at(const config &cfg, const std::string &key, int index)
Creates a child table when resolving name if it doesn't exist yet.
static config & get_child_at(config &cfg, const std::string &key, int index)
static std::string error_message(const std::string &name)
Will throw an exception when trying to access a nonexistent table.
static config & get_child_at(config &cfg, const std::string &key, int index)
static std::string error_message(const std::string &name)
Definitions for the interface to Wesnoth Markup Language (WML).
const config * cfg
@ state_named
The result of .someval.
@ state_start
Represents the initial variable state before processing.
@ state_indexed
The result of .someval[index].
@ state_temporary
The result of .length.
Helper struct to clone the constness of one type to another.
std::conditional_t< is_source_const, const T, T > type
The destination type, possibly const qualified.
typename maybe_const< config, V >::type child_t
typename variable_info_implementation::maybe_const< T, V >::type maybe_const_t
Helper template alias for maybe_const, defined at global scope for convenience.