Revert "Remove macOS compat path for std::variant and std::any"

This reverts commit c2decdfb58.
This commit is contained in:
Celtic Minstrel 2024-07-23 08:23:38 -04:00
parent b372f9e9ae
commit ac431ca9dd
38 changed files with 350 additions and 169 deletions

View file

@ -372,7 +372,7 @@ void advance_unit(map_location loc, const advancement_option &advance_to, bool f
std::vector<int> not_seeing = actions::get_sides_not_seeing(*u);
// Create the advanced unit.
auto [new_unit, use_amla] = std::visit(
auto [new_unit, use_amla] = utils::visit(
[u](const auto& v) {
if constexpr(utils::decayed_is_same<std::string, decltype(v)>) {
return std::pair(get_advanced_unit(*u, v), false);

View file

@ -24,7 +24,7 @@ class config;
#include "map/location.hpp"
#include "units/ptr.hpp"
#include <variant>
#include "utils/variant.hpp"
#include <string>
@ -59,7 +59,7 @@ unit_ptr get_advanced_unit(const unit &u, const std::string &advance_to);
*/
unit_ptr get_amla_unit(const unit &u, const config &mod_option);
using advancement_option = std::variant<std::string /*change type*/, const config* /*apply amla*/>;
using advancement_option = utils::variant<std::string /*change type*/, const config* /*apply amla*/>;
/**
* Function which will advance the unit at @a loc to 'advance_to'.

View file

@ -381,6 +381,9 @@ public:
};
class lua_aspect_visitor
#ifdef USING_BOOST_VARIANT
: public boost::static_visitor<std::string>
#endif
{
static std::string quote_string(const std::string& s);
public:
@ -390,7 +393,7 @@ public:
std::string operator()(double i) const {return std::to_string(i);}
std::string operator()(const std::string& s) const {return quote_string(s);}
std::string operator()(const t_string& s) const {return quote_string(s.str());}
std::string operator()(std::monostate) const {return "nil";}
std::string operator()(utils::monostate) const {return "nil";}
};
template<typename T>

View file

@ -27,7 +27,7 @@
#include "resources.hpp"
#include "serialization/string_utils.hpp"
#include "terrain/filter.hpp"
#include <variant>
#include "utils/variant.hpp"
namespace ai {
@ -114,6 +114,9 @@ public:
};
class leader_aspects_visitor
#ifdef USING_BOOST_VARIANT
: public boost::static_visitor<std::string>
#endif
{
public:
std::string operator()(const bool b) const {
@ -127,10 +130,10 @@ public:
};
template<>
class config_value_translator<std::variant<bool, std::vector<std::string>>> {
class config_value_translator<utils::variant<bool, std::vector<std::string>>> {
public:
static std::variant<bool, std::vector<std::string>> cfg_to_value(const config &cfg)
static utils::variant<bool, std::vector<std::string>> cfg_to_value(const config &cfg)
{
if (cfg["value"].to_bool(true) == cfg["value"].to_bool(false)) {
return cfg["value"].to_bool();
@ -138,17 +141,17 @@ public:
return utils::split(cfg["value"]);
}
static void cfg_to_value(const config &cfg, std::variant<bool, std::vector<std::string>> &value)
static void cfg_to_value(const config &cfg, utils::variant<bool, std::vector<std::string>> &value)
{
value = cfg_to_value(cfg);
}
static void value_to_cfg(const std::variant<bool, std::vector<std::string>> &value, config &cfg)
static void value_to_cfg(const utils::variant<bool, std::vector<std::string>> &value, config &cfg)
{
cfg["value"] = std::visit(leader_aspects_visitor(), value);
cfg["value"] = utils::visit(leader_aspects_visitor(), value);
}
static config value_to_cfg(const std::variant<bool, std::vector<std::string>> &value)
static config value_to_cfg(const utils::variant<bool, std::vector<std::string>> &value)
{
config cfg;
value_to_cfg(value,cfg);

View file

@ -679,7 +679,7 @@ config readonly_context_impl::get_leader_goal() const
return config();
}
std::variant<bool, std::vector<std::string>> readonly_context_impl::get_leader_ignores_keep() const
utils::variant<bool, std::vector<std::string>> readonly_context_impl::get_leader_ignores_keep() const
{
if (leader_ignores_keep_) {
return leader_ignores_keep_->get();
@ -695,7 +695,7 @@ double readonly_context_impl::get_leader_value() const
return 0;
}
std::variant<bool, std::vector<std::string>> readonly_context_impl::get_passive_leader() const
utils::variant<bool, std::vector<std::string>> readonly_context_impl::get_passive_leader() const
{
if (passive_leader_) {
return passive_leader_->get();
@ -703,7 +703,7 @@ std::variant<bool, std::vector<std::string>> readonly_context_impl::get_passive_
return {};
}
std::variant<bool, std::vector<std::string>> readonly_context_impl::get_passive_leader_shares_keep() const
utils::variant<bool, std::vector<std::string>> readonly_context_impl::get_passive_leader_shares_keep() const
{
if (passive_leader_shares_keep_) {
return passive_leader_shares_keep_->get();
@ -1228,9 +1228,9 @@ bool readonly_context_impl::is_active(const std::string &time_of_day, const std:
}
bool readonly_context_impl::applies_to_leader(
const std::variant<bool, std::vector<std::string>>& aspect_value, const std::string& id) const
const utils::variant<bool, std::vector<std::string>>& aspect_value, const std::string& id) const
{
return std::visit(
return utils::visit(
[&id](const auto& v) {
if constexpr(utils::decayed_is_same<bool, decltype(v)>) {
return v;

View file

@ -239,13 +239,13 @@ public:
virtual config get_leader_goal() const = 0;
virtual std::variant<bool, std::vector<std::string>> get_leader_ignores_keep() const = 0;
virtual utils::variant<bool, std::vector<std::string>> get_leader_ignores_keep() const = 0;
virtual double get_leader_value() const = 0;
virtual std::variant<bool, std::vector<std::string>> get_passive_leader() const = 0;
virtual utils::variant<bool, std::vector<std::string>> get_passive_leader() const = 0;
virtual std::variant<bool, std::vector<std::string>> get_passive_leader_shares_keep() const = 0;
virtual utils::variant<bool, std::vector<std::string>> get_passive_leader_shares_keep() const = 0;
virtual const moves_map& get_possible_moves() const = 0;
@ -653,7 +653,7 @@ public:
return target_->get_leader_goal();
}
virtual std::variant<bool, std::vector<std::string>> get_leader_ignores_keep() const override
virtual utils::variant<bool, std::vector<std::string>> get_leader_ignores_keep() const override
{
return target_->get_leader_ignores_keep();
}
@ -663,12 +663,12 @@ public:
return target_->get_leader_value();
}
virtual std::variant<bool, std::vector<std::string>> get_passive_leader() const override
virtual utils::variant<bool, std::vector<std::string>> get_passive_leader() const override
{
return target_->get_passive_leader();
}
virtual std::variant<bool, std::vector<std::string>> get_passive_leader_shares_keep() const override
virtual utils::variant<bool, std::vector<std::string>> get_passive_leader_shares_keep() const override
{
return target_->get_passive_leader_shares_keep();
}
@ -1175,13 +1175,13 @@ public:
virtual config get_leader_goal() const override;
virtual std::variant<bool, std::vector<std::string>> get_leader_ignores_keep() const override;
virtual utils::variant<bool, std::vector<std::string>> get_leader_ignores_keep() const override;
virtual double get_leader_value() const override;
virtual std::variant<bool, std::vector<std::string>> get_passive_leader() const override;
virtual utils::variant<bool, std::vector<std::string>> get_passive_leader() const override;
virtual std::variant<bool, std::vector<std::string>> get_passive_leader_shares_keep() const override;
virtual utils::variant<bool, std::vector<std::string>> get_passive_leader_shares_keep() const override;
virtual const moves_map& get_possible_moves() const override;
@ -1271,7 +1271,7 @@ private:
template<typename T>
void add_known_aspect(const std::string &name, typesafe_aspect_ptr<T>& where);
bool applies_to_leader(const std::variant<bool, std::vector<std::string>> &aspect_value, const std::string &id) const;
bool applies_to_leader(const utils::variant<bool, std::vector<std::string>> &aspect_value, const std::string &id) const;
const config cfg_;
@ -1299,7 +1299,7 @@ private:
mutable keeps_cache keeps_;
typesafe_aspect_ptr<double> leader_aggression_;
typesafe_aspect_ptr<config> leader_goal_;
typesafe_aspect_ptr<std::variant<bool, std::vector<std::string>>> leader_ignores_keep_;
typesafe_aspect_ptr<utils::variant<bool, std::vector<std::string>>> leader_ignores_keep_;
typesafe_aspect_ptr<double> leader_value_;
mutable bool move_maps_enemy_valid_;
mutable bool move_maps_valid_;
@ -1307,8 +1307,8 @@ private:
mutable bool dst_src_enemy_valid_lua_;
mutable bool src_dst_valid_lua_;
mutable bool src_dst_enemy_valid_lua_;
typesafe_aspect_ptr<std::variant<bool, std::vector<std::string>>> passive_leader_;
typesafe_aspect_ptr<std::variant<bool, std::vector<std::string>>> passive_leader_shares_keep_;
typesafe_aspect_ptr<utils::variant<bool, std::vector<std::string>>> passive_leader_;
typesafe_aspect_ptr<utils::variant<bool, std::vector<std::string>>> passive_leader_shares_keep_;
mutable moves_map possible_moves_;
typesafe_aspect_ptr<double> recruitment_diversity_;
typesafe_aspect_ptr<config> recruitment_instructions_;

View file

@ -46,7 +46,7 @@
#include "ai/formula/function_table.hpp" // for ai_function_symbol_table
#include "ai/game_info.hpp" // for move_result_ptr, move_map, etc
#include "ai/formula/candidates.hpp" // for base_candidate_action, etc
#include <variant>
#include "utils/variant.hpp"
#include <ctime> // for time
#include <vector> // for vector, allocator, etc
@ -272,9 +272,9 @@ variant villages_from_set(const Container& villages, const std::set<map_location
}
// TODO: I have no damn idea what to name this function
variant visit_helper(const std::variant<bool, std::vector<std::string>>& input)
variant visit_helper(const utils::variant<bool, std::vector<std::string>>& input)
{
return std::visit(
return utils::visit(
[](const auto& v) {
if constexpr(utils::decayed_is_same<bool, decltype(v)>) {
return variant(v);

View file

@ -409,9 +409,9 @@ static int cfun_ai_get_leader_goal(lua_State *L)
namespace
{
// TODO: name this something better
void visit_helper(lua_State* L, const std::variant<bool, std::vector<std::string>>& input)
void visit_helper(lua_State* L, const utils::variant<bool, std::vector<std::string>>& input)
{
std::visit(
utils::visit(
[L](const auto& v) {
if constexpr(utils::decayed_is_same<bool, decltype(v)>) {
lua_pushboolean(L, v);

View file

@ -119,11 +119,11 @@ inline std::shared_ptr<std::string> lua_object<std::string>::to_type(lua_State *
}
template <>
inline void lua_object<std::variant<bool, std::vector<std::string>>>::from_type(lua_State *L, std::shared_ptr<std::variant<bool, std::vector<std::string>>> value)
inline void lua_object<utils::variant<bool, std::vector<std::string>>>::from_type(lua_State *L, std::shared_ptr<utils::variant<bool, std::vector<std::string>>> value)
{
if(value) {
// TODO: this is is duplicated as a helper function in ai/lua/core.cpp
std::visit(
utils::visit(
[L](const auto& v) {
if constexpr(utils::decayed_is_same<bool, decltype(v)>) {
lua_pushboolean(L, v);
@ -140,10 +140,10 @@ inline void lua_object<std::variant<bool, std::vector<std::string>>>::from_type(
}
template <>
inline std::shared_ptr< std::variant<bool, std::vector<std::string>> > lua_object< std::variant<bool, std::vector<std::string>> >::to_type(lua_State *L, int n)
inline std::shared_ptr< utils::variant<bool, std::vector<std::string>> > lua_object< utils::variant<bool, std::vector<std::string>> >::to_type(lua_State *L, int n)
{
if (lua_isboolean(L, n)) {
return std::make_shared<std::variant<bool, std::vector<std::string>>>(luaW_toboolean(L, n));
return std::make_shared<utils::variant<bool, std::vector<std::string>>>(luaW_toboolean(L, n));
} else {
auto v = std::make_shared<std::vector<std::string>>();
int l = lua_rawlen(L, n);
@ -156,7 +156,7 @@ inline std::shared_ptr< std::variant<bool, std::vector<std::string>> > lua_objec
v->push_back(s);
}
return std::make_shared<std::variant<bool, std::vector<std::string>>>(*v);
return std::make_shared<utils::variant<bool, std::vector<std::string>>>(*v);
}
}

View file

@ -273,10 +273,10 @@ const std::string holder::get_ai_overview()
s << "caution: " << this->ai_->get_caution() << std::endl;
s << "grouping: " << this->ai_->get_grouping() << std::endl;
s << "leader_aggression: " << this->ai_->get_leader_aggression() << std::endl;
s << "leader_ignores_keep: " << std::visit(leader_aspects_visitor(), lik) << std::endl;
s << "leader_ignores_keep: " << utils::visit(leader_aspects_visitor(), lik) << std::endl;
s << "leader_value: " << this->ai_->get_leader_value() << std::endl;
s << "passive_leader: " << std::visit(leader_aspects_visitor(), pl) << std::endl;
s << "passive_leader_shares_keep: " << std::visit(leader_aspects_visitor(), plsk) << std::endl;
s << "passive_leader: " << utils::visit(leader_aspects_visitor(), pl) << std::endl;
s << "passive_leader_shares_keep: " << utils::visit(leader_aspects_visitor(), plsk) << std::endl;
s << "recruitment_diversity: " << this->ai_->get_recruitment_diversity() << std::endl;
s << "recruitment_instructions: " << std::endl << "----config begin----" << std::endl;
s << this->ai_->get_recruitment_instructions() << "-----config end-----" << std::endl;

View file

@ -209,16 +209,16 @@ static register_aspect_factory< composite_aspect<double>>
static register_aspect_factory< composite_aspect<config>>
leader_goal__composite_aspect_factory("leader_goal*composite_aspect");
static register_aspect_factory< composite_aspect<std::variant<bool, std::vector<std::string>>>>
static register_aspect_factory< composite_aspect<utils::variant<bool, std::vector<std::string>>>>
leader_igores_keep__composite_aspect_factory("leader_ignores_keep*composite_aspect");
static register_aspect_factory< composite_aspect<double>>
leader_value__composite_aspect_factory("leader_value*composite_aspect");
static register_aspect_factory< composite_aspect<std::variant<bool, std::vector<std::string>>>>
static register_aspect_factory< composite_aspect<utils::variant<bool, std::vector<std::string>>>>
passive_leader__composite_aspect_factory("passive_leader*composite_aspect");
static register_aspect_factory< composite_aspect<std::variant<bool, std::vector<std::string>>>>
static register_aspect_factory< composite_aspect<utils::variant<bool, std::vector<std::string>>>>
passive_leader_shares_keep__composite_aspect_factory("passive_leader_shares_keep*composite_aspect");
static register_aspect_factory< composite_aspect<double>>
@ -289,16 +289,16 @@ static register_aspect_factory< standard_aspect<double>>
static register_aspect_factory< standard_aspect<config>>
leader_goal__standard_aspect_factory("leader_goal*standard_aspect");
static register_aspect_factory< standard_aspect<std::variant<bool, std::vector<std::string>>>>
static register_aspect_factory< standard_aspect<utils::variant<bool, std::vector<std::string>>>>
leader_ignores_keep__standard_aspect_factory("leader_ignores_keep*standard_aspect");
static register_aspect_factory< standard_aspect<double>>
leader_value__standard_aspect_factory("leader_value*standard_aspect");
static register_aspect_factory< standard_aspect<std::variant<bool, std::vector<std::string>>>>
static register_aspect_factory< standard_aspect<utils::variant<bool, std::vector<std::string>>>>
passive_leader__standard_aspect_factory("passive_leader*standard_aspect");
static register_aspect_factory< standard_aspect<std::variant<bool, std::vector<std::string>>>>
static register_aspect_factory< standard_aspect<utils::variant<bool, std::vector<std::string>>>>
passive_leader_shares_keep__standard_aspect_factory("passive_leader_shares_keep*standard_aspect");
static register_aspect_factory< standard_aspect<double>>
@ -373,16 +373,16 @@ static register_aspect_factory< standard_aspect<double>>
static register_aspect_factory< standard_aspect<config>>
leader_goal__standard_aspect_factory2("leader_goal*");
static register_aspect_factory< standard_aspect<std::variant<bool, std::vector<std::string>>>>
static register_aspect_factory< standard_aspect<utils::variant<bool, std::vector<std::string>>>>
leader_ignores_keep__standard_aspect_factory2("leader_ignores_keep*");
static register_aspect_factory< standard_aspect<double>>
leader_value__standard_aspect_factory2("leader_value*");
static register_aspect_factory< standard_aspect<std::variant<bool, std::vector<std::string>>>>
static register_aspect_factory< standard_aspect<utils::variant<bool, std::vector<std::string>>>>
passive_leader__standard_aspect_factory2("passive_leader*");
static register_aspect_factory< standard_aspect<std::variant<bool, std::vector<std::string>>>>
static register_aspect_factory< standard_aspect<utils::variant<bool, std::vector<std::string>>>>
passive_leader_shares_keep__standard_aspect_factory2("passive_leader_shares_keep*");
static register_aspect_factory< standard_aspect<double>>
@ -453,16 +453,16 @@ static register_lua_aspect_factory< lua_aspect<double>>
static register_lua_aspect_factory< lua_aspect<config>>
leader_goal__lua_aspect_factory("leader_goal*lua_aspect");
static register_lua_aspect_factory< lua_aspect<std::variant<bool, std::vector<std::string>>>>
static register_lua_aspect_factory< lua_aspect<utils::variant<bool, std::vector<std::string>>>>
leader_ignores_keep__lua_aspect_factory("leader_ignores_keep*lua_aspect");
static register_lua_aspect_factory< lua_aspect<double>>
leader_value__lua_aspect_factory("leader_value*lua_aspect");
static register_lua_aspect_factory< lua_aspect<std::variant<bool, std::vector<std::string>>>>
static register_lua_aspect_factory< lua_aspect<utils::variant<bool, std::vector<std::string>>>>
passive_leader__lua_aspect_factory("passive_leader*lua_aspect");
static register_lua_aspect_factory< lua_aspect<std::variant<bool, std::vector<std::string>>>>
static register_lua_aspect_factory< lua_aspect<utils::variant<bool, std::vector<std::string>>>>
passive_leader_shares_keep__lua_aspect_factory("passive_leader_shares_keep*lua_aspect");
static register_lua_aspect_factory< lua_aspect<double>>

View file

@ -251,9 +251,9 @@ void config_attribute_value::write_if_not_empty(const t_string& v)
bool config_attribute_value::to_bool(bool def) const
{
if(const yes_no* p = std::get_if<yes_no>(&value_))
if(const yes_no* p = utils::get_if<yes_no>(&value_))
return *p;
if(const true_false* p = std::get_if<true_false>(&value_))
if(const true_false* p = utils::get_if<true_false>(&value_))
return *p;
// No other types are ever recognized as boolean.
@ -265,12 +265,15 @@ namespace
/** Visitor for converting a variant to a numeric type (T). */
template<typename T>
class attribute_numeric_visitor
#ifdef USING_BOOST_VARIANT
: public boost::static_visitor<T>
#endif
{
public:
// Constructor stores the default value.
attribute_numeric_visitor(T def) : def_(def) {}
T operator()(const std::monostate&) const { return def_; }
T operator()(const utils::monostate&) const { return def_; }
T operator()(bool) const { return def_; }
T operator()(int i) const { return static_cast<T>(i); }
T operator()(unsigned long long u) const { return static_cast<T>(u); }
@ -315,13 +318,16 @@ double config_attribute_value::to_double(double def) const
/** Visitor for converting a variant to a string. */
class config_attribute_value::string_visitor
#ifdef USING_BOOST_VARIANT
: public boost::static_visitor<std::string>
#endif
{
const std::string default_;
public:
string_visitor(const std::string& fallback) : default_(fallback) {}
std::string operator()(const std::monostate &) const { return default_; }
std::string operator()(const utils::monostate &) const { return default_; }
std::string operator()(const yes_no & b) const { return b.str(); }
std::string operator()(const true_false & b) const { return b.str(); }
std::string operator()(int i) const { return std::to_string(i); }
@ -338,7 +344,7 @@ std::string config_attribute_value::str(const std::string& fallback) const
t_string config_attribute_value::t_str() const
{
if(const t_string* p = std::get_if<t_string>(&value_)) {
if(const t_string* p = utils::get_if<t_string>(&value_)) {
return *p;
}
@ -350,7 +356,7 @@ t_string config_attribute_value::t_str() const
*/
bool config_attribute_value::blank() const
{
return std::holds_alternative<std::monostate>(value_);
return utils::holds_alternative<utils::monostate>(value_);
}
/**
@ -362,7 +368,7 @@ bool config_attribute_value::empty() const
return true;
}
if(const std::string* p = std::get_if<std::string>(&value_)) {
if(const std::string* p = utils::get_if<std::string>(&value_)) {
return p->empty();
}
@ -371,6 +377,9 @@ bool config_attribute_value::empty() const
/** Visitor handling equality checks. */
class config_attribute_value::equality_visitor
#ifdef USING_BOOST_VARIANT
: public boost::static_visitor<bool>
#endif
{
public:
// Most generic: not equal.
@ -406,7 +415,7 @@ public:
*/
bool config_attribute_value::operator==(const config_attribute_value& other) const
{
return std::visit(equality_visitor(), value_, other.value_);
return utils::visit(equality_visitor(), value_, other.value_);
}
/**

View file

@ -29,7 +29,7 @@
#pragma once
#include "tstring.hpp"
#include <variant>
#include "utils/variant.hpp"
#include <climits>
#include <ctime>
@ -96,7 +96,7 @@ private:
// use few types (to keep the overhead low), we do have use cases for
// fractions (double) and huge numbers (up to the larger of LLONG_MAX
// and SIZE_MAX).
typedef std::variant<std::monostate,
typedef utils::variant<utils::monostate,
true_false, yes_no,
int, unsigned long long, double,
std::string, t_string
@ -216,7 +216,7 @@ public:
template <typename V>
auto apply_visitor(const V & visitor) const
{
return std::visit(visitor, value_);
return utils::visit(visitor, value_);
}
private:
@ -225,8 +225,10 @@ private:
static const std::string s_true, s_false;
};
#ifndef USING_BOOST_VARIANT
/** Specialize operator<< for monostate. Boost already does this, but the STL does not. */
inline std::ostream& operator<<(std::ostream& os, const std::monostate&) { return os; }
#endif
namespace utils
{

View file

@ -504,6 +504,9 @@ int unit_type_callable::do_compare(const formula_callable* callable) const
}
struct fai_variant_visitor
#ifdef USING_BOOST_VARIANT
: public boost::static_visitor<variant>
#endif
{
variant operator()(bool b) const { return variant(b ? 1 : 0); }
variant operator()(int i) const { return variant(i); }
@ -514,7 +517,7 @@ struct fai_variant_visitor
// (or should we assume that such strings will be translatable?).
variant operator()(const std::string& s) const { return variant(s); }
variant operator()(const t_string& s) const { return variant(s.str()); }
variant operator()(std::monostate) const { return variant(); }
variant operator()(utils::monostate) const { return variant(); }
};
variant config_callable::get_value(const std::string& key) const

View file

@ -64,7 +64,7 @@ variant_iterator::variant_iterator()
{
}
variant_iterator::variant_iterator(const variant_value_base* value, const std::any& iter)
variant_iterator::variant_iterator(const variant_value_base* value, const utils::any& iter)
: type_(value->get_type())
, container_(value)
, iter_(iter)

View file

@ -205,7 +205,7 @@ public:
* @param value A pointer to a variant value representing the container.
* @param iter An underlying iterator for the underlying container.
*/
variant_iterator(const variant_value_base* value, const std::any& iter);
variant_iterator(const variant_value_base* value, const utils::any& iter);
variant operator*() const;
variant_iterator& operator++();
@ -217,7 +217,7 @@ public:
private:
formula_variant::type type_;
const variant_value_base* container_;
std::any iter_;
utils::any iter_;
};
}

View file

@ -26,7 +26,7 @@ boost::iterator_range<variant_iterator> variant_value_base::make_iterator() cons
return {variant_iterator(), variant_iterator()};
}
variant variant_value_base::deref_iterator(const std::any& /*iter*/) const
variant variant_value_base::deref_iterator(const utils::any& /*iter*/) const
{
return variant();
}
@ -166,23 +166,23 @@ boost::iterator_range<variant_iterator> variant_callable::make_iterator() const
return {variant_iterator(this, inputs.cbegin()), variant_iterator(this, inputs.cend())};
}
variant variant_callable::deref_iterator(const std::any& iter) const
variant variant_callable::deref_iterator(const utils::any& iter) const
{
if(!callable_) {
return variant();
}
return callable_->query_value(std::any_cast<const formula_input_vector::const_iterator&>(iter)->name);
return callable_->query_value(utils::any_cast<const formula_input_vector::const_iterator&>(iter)->name);
}
void variant_callable::iterator_inc(std::any& iter) const
void variant_callable::iterator_inc(utils::any& iter) const
{
++std::any_cast<formula_input_vector::const_iterator&>(iter);
++utils::any_cast<formula_input_vector::const_iterator&>(iter);
}
void variant_callable::iterator_dec(std::any& iter) const
void variant_callable::iterator_dec(utils::any& iter) const
{
--std::any_cast<formula_input_vector::const_iterator&>(iter);
--utils::any_cast<formula_input_vector::const_iterator&>(iter);
}
std::string variant_string::get_serialized_string() const
@ -270,21 +270,21 @@ boost::iterator_range<variant_iterator> variant_container<T>::make_iterator() co
}
template<typename T>
void variant_container<T>::iterator_inc(std::any& iter) const
void variant_container<T>::iterator_inc(utils::any& iter) const
{
++std::any_cast<typename T::const_iterator&>(iter);
++utils::any_cast<typename T::const_iterator&>(iter);
}
template<typename T>
void variant_container<T>::iterator_dec(std::any& iter) const
void variant_container<T>::iterator_dec(utils::any& iter) const
{
--std::any_cast<typename T::const_iterator&>(iter);
--utils::any_cast<typename T::const_iterator&>(iter);
}
template<typename T>
bool variant_container<T>::iterator_equals(const std::any& first, const std::any& second) const
bool variant_container<T>::iterator_equals(const utils::any& first, const utils::any& second) const
{
return std::any_cast<typename T::const_iterator>(first) == std::any_cast<typename T::const_iterator>(second);
return utils::any_cast<typename T::const_iterator>(first) == utils::any_cast<typename T::const_iterator>(second);
}
// Force compilation of the following template instantiations
@ -341,9 +341,9 @@ bool variant_list::less_than(variant_value_base& other) const
return num_elements() < other.num_elements();
}
variant variant_list::deref_iterator(const std::any& iter) const
variant variant_list::deref_iterator(const utils::any& iter) const
{
return *std::any_cast<const variant_vector::const_iterator&>(iter);
return *utils::any_cast<const variant_vector::const_iterator&>(iter);
}
std::string variant_map::to_string_detail(const variant_map_raw::value_type& container_val, mod_func_t mod_func) const
@ -367,9 +367,9 @@ bool variant_map::less_than(variant_value_base& other) const
return get_container() < value_ref_cast<variant_map>(other).get_container();
}
variant variant_map::deref_iterator(const std::any& iter) const
variant variant_map::deref_iterator(const utils::any& iter) const
{
const variant_map_raw::value_type& p = *std::any_cast<const variant_map_raw::const_iterator&>(iter);
const variant_map_raw::value_type& p = *utils::any_cast<const variant_map_raw::const_iterator&>(iter);
auto the_pair = std::make_shared<key_value_pair>(p.first, p.second);
return variant(the_pair);
}

View file

@ -17,7 +17,7 @@
#include "exceptions.hpp"
#include "formula/callable_fwd.hpp"
#include "formula_variant.hpp"
#include <any>
#include "utils/any.hpp"
#include "utils/general.hpp"
#include <functional>
@ -139,7 +139,7 @@ public:
/**
* Creates an iterator pair that can be used for iteration.
* For an iterable type, it should use the two-argument constructor of variant-iterator,
* passing the underlying iterator as the std::any parameter.
* passing the underlying iterator as the utils::any parameter.
*
* This creates both the begin and end iterator, but the variant implementation
* discards one of the two.
@ -152,7 +152,7 @@ public:
*
* @param iter The opaque reference that was passed to the variant_iterator by @ref make_iterator.
*/
virtual variant deref_iterator(const std::any& iter) const;
virtual variant deref_iterator(const utils::any& iter) const;
/**
* Implements the increment functionality of variant_iterator
@ -160,7 +160,7 @@ public:
*
* The parameter is an opaque reference that was passed to the variant_iterator by @ref make_iterator.
*/
virtual void iterator_inc(std::any&) const {}
virtual void iterator_inc(utils::any&) const {}
/**
* Implements the decrement functionality of variant_iterator
@ -168,7 +168,7 @@ public:
*
* The parameter is an opaque reference that was passed to the variant_iterator by @ref make_iterator.
*/
virtual void iterator_dec(std::any&) const {}
virtual void iterator_dec(utils::any&) const {}
/**
* Implements the equality functionality of variant_iterator
@ -179,7 +179,7 @@ public:
* The first parameter is an opaque reference that was passed to the variant_iterator by @ref make_iterator.
* The second parameter is an opaque reference that was passed to the variant_iterator by @ref make_iterator.
*/
virtual bool iterator_equals(const std::any& /*first*/, const std::any& /*second*/) const
virtual bool iterator_equals(const utils::any& /*first*/, const utils::any& /*second*/) const
{
return true;
}
@ -336,11 +336,11 @@ public:
}
virtual boost::iterator_range<variant_iterator> make_iterator() const override;
virtual variant deref_iterator(const std::any& iter) const override;
virtual variant deref_iterator(const utils::any& iter) const override;
virtual void iterator_inc(std::any& iter) const override;
virtual void iterator_dec(std::any& iter) const override;
virtual bool iterator_equals(const std::any& /*first*/, const std::any& /*second*/) const override
virtual void iterator_inc(utils::any& iter) const override;
virtual void iterator_dec(utils::any& iter) const override;
virtual bool iterator_equals(const utils::any& /*first*/, const utils::any& /*second*/) const override
{
return true; // TODO: implement
}
@ -463,9 +463,9 @@ public:
// specializations and leave the deref function to the derived classes.
virtual boost::iterator_range<variant_iterator> make_iterator() const override;
virtual void iterator_inc(std::any&) const override;
virtual void iterator_dec(std::any&) const override;
virtual bool iterator_equals(const std::any& first, const std::any& second) const override;
virtual void iterator_inc(utils::any&) const override;
virtual void iterator_dec(utils::any&) const override;
virtual bool iterator_equals(const utils::any& first, const utils::any& second) const override;
protected:
using mod_func_t = std::function<std::string(const variant&)>;
@ -506,7 +506,7 @@ public:
return type;
}
virtual variant deref_iterator(const std::any&) const override;
virtual variant deref_iterator(const utils::any&) const override;
private:
virtual std::string to_string_detail(const variant_vector::value_type& container_val, mod_func_t mod_func) const override
@ -532,7 +532,7 @@ public:
return type;
}
virtual variant deref_iterator(const std::any&) const override;
virtual variant deref_iterator(const utils::any&) const override;
private:
virtual std::string to_string_detail(const variant_map_raw::value_type& container_val, mod_func_t mod_func) const override;

View file

@ -93,7 +93,7 @@ connection::connection(const std::string& host, const std::string& service)
connection::~connection()
{
if(auto socket = std::get_if<tls_socket>(&socket_)) {
if(auto socket = utils::get_if<tls_socket>(&socket_)) {
boost::system::error_code ec;
// this sends close_notify for secure connection shutdown
(*socket)->async_shutdown([](const boost::system::error_code&) {} );
@ -109,7 +109,7 @@ void connection::handle_resolve(const boost::system::error_code& ec, results_typ
throw system_error(ec);
}
boost::asio::async_connect(*std::get<raw_socket>(socket_), results,
boost::asio::async_connect(*utils::get<raw_socket>(socket_), results,
std::bind(&connection::handle_connect, this, std::placeholders::_1, std::placeholders::_2));
}
@ -131,12 +131,12 @@ void connection::handshake()
static const uint32_t tls_handshake = htonl(uint32_t(1));
boost::asio::async_write(
*std::get<raw_socket>(socket_),
*utils::get<raw_socket>(socket_),
boost::asio::buffer(use_tls_ ? reinterpret_cast<const char*>(&tls_handshake) : reinterpret_cast<const char*>(&handshake), 4),
std::bind(&connection::handle_write, this, std::placeholders::_1, std::placeholders::_2)
);
boost::asio::async_read(*std::get<raw_socket>(socket_), boost::asio::buffer(reinterpret_cast<std::byte*>(&handshake_response_), 4),
boost::asio::async_read(*utils::get<raw_socket>(socket_), boost::asio::buffer(reinterpret_cast<std::byte*>(&handshake_response_), 4),
std::bind(&connection::handle_handshake, this, std::placeholders::_1));
}
@ -182,11 +182,11 @@ void connection::handle_handshake(const boost::system::error_code& ec)
if(handshake_response_ == 0x00000000) {
load_tls_root_certs(tls_context_);
raw_socket s { std::move(std::get<raw_socket>(socket_)) };
raw_socket s { std::move(utils::get<raw_socket>(socket_)) };
tls_socket ts { new tls_socket::element_type { std::move(*s), tls_context_ } };
socket_ = std::move(ts);
auto& socket { *std::get<tls_socket>(socket_) };
auto& socket { *utils::get<tls_socket>(socket_) };
socket.set_verify_mode(
boost::asio::ssl::verify_peer |
@ -220,10 +220,10 @@ void connection::fallback_to_unencrypted()
assert(use_tls_ == true);
use_tls_ = false;
boost::asio::ip::tcp::endpoint endpoint { std::get<raw_socket>(socket_)->remote_endpoint() };
std::get<raw_socket>(socket_)->close();
boost::asio::ip::tcp::endpoint endpoint { utils::get<raw_socket>(socket_)->remote_endpoint() };
utils::get<raw_socket>(socket_)->close();
std::get<raw_socket>(socket_)->async_connect(endpoint,
utils::get<raw_socket>(socket_)->async_connect(endpoint,
std::bind(&connection::handle_connect, this, std::placeholders::_1, endpoint));
}
@ -244,7 +244,7 @@ void connection::transfer(const config& request, config& response)
auto bufs = split_buffer(write_buf_->data());
bufs.push_front(boost::asio::buffer(reinterpret_cast<const char*>(&payload_size_), 4));
std::visit([this, &bufs, &response](auto&& socket) {
utils::visit([this, &bufs, &response](auto&& socket) {
boost::asio::async_write(*socket, bufs,
std::bind(&connection::is_write_complete, this, std::placeholders::_1, std::placeholders::_2),
std::bind(&connection::handle_write, this, std::placeholders::_1, std::placeholders::_2));
@ -257,7 +257,7 @@ void connection::transfer(const config& request, config& response)
void connection::cancel()
{
std::visit([](auto&& socket) {
utils::visit([](auto&& socket) {
if(socket->lowest_layer().is_open()) {
boost::system::error_code ec;

View file

@ -32,7 +32,7 @@
#endif
#include "exceptions.hpp"
#include <variant>
#include "utils/variant.hpp"
#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/tcp.hpp>
@ -103,7 +103,7 @@ public:
{
// Calling this function before connection is ready may return wrong result
assert(done_);
return std::holds_alternative<tls_socket>(socket_);
return utils::holds_alternative<tls_socket>(socket_);
}
std::size_t bytes_to_write() const
@ -138,7 +138,7 @@ private:
typedef std::unique_ptr<boost::asio::ip::tcp::socket> raw_socket;
typedef std::unique_ptr<boost::asio::ssl::stream<raw_socket::element_type>> tls_socket;
typedef std::variant<raw_socket, tls_socket> any_socket;
typedef utils::variant<raw_socket, tls_socket> any_socket;
bool use_tls_;
any_socket socket_;

View file

@ -551,11 +551,14 @@ void luaW_pushtstring(lua_State *L, const t_string& v)
namespace {
struct luaW_pushscalar_visitor
#ifdef USING_BOOST_VARIANT
: boost::static_visitor<>
#endif
{
lua_State *L;
luaW_pushscalar_visitor(lua_State *l): L(l) {}
void operator()(const std::monostate&) const
void operator()(const utils::monostate&) const
{ lua_pushnil(L); }
void operator()(bool b) const
{ lua_pushboolean(L, b); }

View file

@ -342,10 +342,10 @@ static int impl_unit_get(lua_State *L)
unit::upkeep_t upkeep = u.upkeep_raw();
// Need to keep these separate in order to ensure an int value is always used if applicable.
if(int* v = std::get_if<int>(&upkeep)) {
if(int* v = utils::get_if<int>(&upkeep)) {
lua_push(L, *v);
} else {
const std::string type = std::visit(unit::upkeep_type_visitor{}, upkeep);
const std::string type = utils::visit(unit::upkeep_type_visitor{}, upkeep);
lua_push(L, type);
}

View file

@ -524,6 +524,9 @@ inline std::string escaped_string(const std::string& value)
}
class write_key_val_visitor
#ifdef USING_BOOST_VARIANT
: public boost::static_visitor<void>
#endif
{
public:
write_key_val_visitor(std::ostream& out, unsigned level, std::string& textdomain, const std::string& key)
@ -546,7 +549,7 @@ public:
// Specialized visitors for things that go in quotes:
//
void operator()(const std::monostate&) const
void operator()(const utils::monostate&) const
{
// Treat blank values as nonexistent which fits better than treating them as empty strings.
}

View file

@ -22,7 +22,7 @@
#include "config.hpp"
#include <optional>
#include <variant>
#include "utils/variant.hpp"
struct is_translatable
{
@ -36,7 +36,7 @@ struct is_translatable
{
return true;
}
bool operator()(const std::monostate&) const
bool operator()(const utils::monostate&) const
{
return true;
}

View file

@ -482,7 +482,7 @@ void server::load_config()
std::ostream& operator<<(std::ostream& o, const server::request& r)
{
o << '[' << (std::holds_alternative<tls_socket_ptr>(r.sock) ? "+" : "") << r.addr << ' ' << r.cmd << "] ";
o << '[' << (utils::holds_alternative<tls_socket_ptr>(r.sock) ? "+" : "") << r.addr << ' ' << r.cmd << "] ";
return o;
}
@ -842,11 +842,11 @@ void server::send_message(const std::string& msg, const any_socket_ptr& sock)
const auto& escaped_msg = simple_wml_escape(msg);
simple_wml::document doc;
doc.root().add_child("message").set_attr_dup("message", escaped_msg.c_str());
std::visit([this, &doc](auto&& sock) { async_send_doc_queued(sock, doc); }, sock);
utils::visit([this, &doc](auto&& sock) { async_send_doc_queued(sock, doc); }, sock);
}
inline std::string client_address(const any_socket_ptr& sock) {
return std::visit([](auto&& sock) { return ::client_address(sock); }, sock);
return utils::visit([](auto&& sock) { return ::client_address(sock); }, sock);
}
void server::send_error(const std::string& msg, const any_socket_ptr& sock)
@ -855,7 +855,7 @@ void server::send_error(const std::string& msg, const any_socket_ptr& sock)
const auto& escaped_msg = simple_wml_escape(msg);
simple_wml::document doc;
doc.root().add_child("error").set_attr_dup("message", escaped_msg.c_str());
std::visit([this, &doc](auto&& sock) { async_send_doc_queued(sock, doc); }, sock);
utils::visit([this, &doc](auto&& sock) { async_send_doc_queued(sock, doc); }, sock);
}
void server::send_error(const std::string& msg, const std::string& extra_data, unsigned int status_code, const any_socket_ptr& sock)
@ -876,7 +876,7 @@ void server::send_error(const std::string& msg, const std::string& extra_data, u
err_cfg.set_attr_dup("extra_data", escaped_extra_data.c_str());
err_cfg.set_attr_dup("status_code", escaped_status_str.c_str());
std::visit([this, &doc](auto&& sock) { async_send_doc_queued(sock, doc); }, sock);
utils::visit([this, &doc](auto&& sock) { async_send_doc_queued(sock, doc); }, sock);
}
optional_config server::get_addon(const std::string& id)
@ -954,7 +954,7 @@ void server::handle_server_id(const server::request& req)
simple_wml::document doc(wml.c_str(), simple_wml::INIT_STATIC);
doc.compress();
std::visit([this, &doc](auto&& sock) { async_send_doc_queued(sock, doc); }, req.sock);
utils::visit([this, &doc](auto&& sock) { async_send_doc_queued(sock, doc); }, req.sock);
}
void server::handle_request_campaign_list(const server::request& req)
@ -1055,7 +1055,7 @@ void server::handle_request_campaign_list(const server::request& req)
simple_wml::document doc(wml.c_str(), simple_wml::INIT_STATIC);
doc.compress();
std::visit([this, &doc](auto&& sock) { async_send_doc_queued(sock, doc); }, req.sock);
utils::visit([this, &doc](auto&& sock) { async_send_doc_queued(sock, doc); }, req.sock);
}
void server::handle_request_campaign(const server::request& req)
@ -1167,7 +1167,7 @@ void server::handle_request_campaign(const server::request& req)
LOG_CS << req << "Sending add-on '" << name << "' version: " << from << " -> " << to << " (delta)";
std::visit([this, &req, &doc](auto && sock) {
utils::visit([this, &req, &doc](auto && sock) {
coro_send_doc(sock, doc, req.yield);
}, req.sock);
@ -1185,7 +1185,7 @@ void server::handle_request_campaign(const server::request& req)
}
LOG_CS << req << "Sending add-on '" << name << "' version: " << to << " size: " << full_pack_size / 1024 << " KiB";
std::visit([this, &req, &full_pack_path](auto&& socket) {
utils::visit([this, &req, &full_pack_path](auto&& socket) {
coro_send_file(socket, full_pack_path, req.yield);
}, req.sock);
}
@ -1242,7 +1242,7 @@ void server::handle_request_campaign_hash(const server::request& req)
}
LOG_CS << req << "Sending add-on hash index for '" << req.cfg["name"] << "' size: " << file_size / 1024 << " KiB";
std::visit([this, &path, &req](auto&& socket) {
utils::visit([this, &path, &req](auto&& socket) {
coro_send_file(socket, path, req.yield);
}, req.sock);
}

View file

@ -175,7 +175,7 @@ void server_base::serve(boost::asio::yield_context yield, boost::asio::ip::tcp::
}
final_socket = tls_socket_ptr { new tls_socket_ptr::element_type(std::move(*socket), tls_context_) };
std::get<tls_socket_ptr>(final_socket)->async_handshake(boost::asio::ssl::stream_base::server, yield[error]);
utils::get<tls_socket_ptr>(final_socket)->async_handshake(boost::asio::ssl::stream_base::server, yield[error]);
if(error) {
ERR_SERVER << "TLS handshake failed: " << error.message();
return;
@ -187,7 +187,7 @@ void server_base::serve(boost::asio::yield_context yield, boost::asio::ip::tcp::
return;
}
std::visit([this](auto&& socket) {
utils::visit([this](auto&& socket) {
const std::string ip = client_address(socket);
const std::string reason = is_ip_banned(ip);

View file

@ -23,7 +23,7 @@
#include "exceptions.hpp"
#include "server/common/simple_wml.hpp"
#include <variant>
#include "utils/variant.hpp"
#include "utils/general.hpp"
#ifdef _WIN32
@ -49,7 +49,7 @@ class config;
typedef std::shared_ptr<boost::asio::ip::tcp::socket> socket_ptr;
typedef std::shared_ptr<boost::asio::ssl::stream<socket_ptr::element_type>> tls_socket_ptr;
typedef std::variant<socket_ptr, tls_socket_ptr> any_socket_ptr;
typedef utils::variant<socket_ptr, tls_socket_ptr> any_socket_ptr;
struct server_shutdown : public game::error
{

View file

@ -1934,7 +1934,7 @@ template<class SocketPtr> void server::send_server_message(SocketPtr socket, con
void server::disconnect_player(player_iterator player)
{
std::visit([](auto&& socket) {
utils::visit([](auto&& socket) {
if constexpr (utils::decayed_is_same<tls_socket_ptr, decltype(socket)>) {
socket->async_shutdown([socket](...) {});
const char buffer[] = "";
@ -2659,7 +2659,7 @@ void server::kickban_handler(
for(auto user : users_to_kick) {
*out << "\nKicked " << user->info().name() << " (" << user->client_ip() << ").";
std::visit([this,reason](auto&& socket) { async_send_error(socket, "You have been banned. Reason: " + reason); }, user->socket());
utils::visit([this,reason](auto&& socket) { async_send_error(socket, "You have been banned. Reason: " + reason); }, user->socket());
disconnect_player(user);
}
}
@ -2801,7 +2801,7 @@ void server::kick_handler(const std::string& /*issuer_name*/,
*out << "Kicked " << player->name() << " (" << player->client_ip() << "). '"
<< kick_message << "'";
std::visit([this, &kick_message](auto&& socket) { async_send_error(socket, kick_message); }, player->socket());
utils::visit([this, &kick_message](auto&& socket) { async_send_error(socket, kick_message); }, player->socket());
disconnect_player(player);
}

View file

@ -69,14 +69,14 @@ private:
public:
template<class SocketPtr> void send_server_message(SocketPtr socket, const std::string& message, const std::string& type);
void send_server_message(player_iterator player, const std::string& message, const std::string& type) {
std::visit(
utils::visit(
[this, &message, &type](auto&& socket) { send_server_message(socket, message, type); },
player->socket()
);
}
void send_to_lobby(simple_wml::document& data, std::optional<player_iterator> exclude = {});
void send_to_player(player_iterator player, simple_wml::document& data) {
std::visit(
utils::visit(
[this, &data](auto&& socket) { async_send_doc_queued(socket, data); },
player->socket()
);

View file

@ -539,12 +539,15 @@ namespace {
template<typename T, typename TFuncFormula>
class get_ability_value_visitor
#ifdef USING_BOOST_VARIANT
: public boost::static_visitor<T>
#endif
{
public:
// Constructor stores the default value.
get_ability_value_visitor(T def, const TFuncFormula& formula_handler) : def_(def), formula_handler_(formula_handler) {}
T operator()(const std::monostate&) const { return def_; }
T operator()(const utils::monostate&) const { return def_; }
T operator()(bool) const { return def_; }
T operator()(int i) const { return static_cast<T>(i); }
T operator()(unsigned long long u) const { return static_cast<T>(u); }

View file

@ -199,6 +199,9 @@ struct unit_filter_attribute_literal : public unit_filter_base
};
class contains_dollar_visitor
#ifdef USING_BOOST_VARIANT
: public boost::static_visitor<bool>
#endif
{
public:
contains_dollar_visitor() {}
@ -502,7 +505,7 @@ void unit_filter_compound::fill(vconfig cfg)
},
[](unit::upkeep_t upkeep, const unit_filter_args& args)
{
return args.u.upkeep() == std::visit(unit::upkeep_value_visitor{args.u}, upkeep);
return args.u.upkeep() == utils::visit(unit::upkeep_value_visitor{args.u}, upkeep);
}
);

View file

@ -1774,12 +1774,12 @@ int unit::upkeep() const
return 0;
}
return std::visit(upkeep_value_visitor{*this}, upkeep_);
return utils::visit(upkeep_value_visitor{*this}, upkeep_);
}
bool unit::loyal() const
{
return std::holds_alternative<upkeep_loyal>(upkeep_);
return utils::holds_alternative<upkeep_loyal>(upkeep_);
}
void unit::set_loyal(bool loyal)
@ -2866,7 +2866,7 @@ void unit::parse_upkeep(const config::attribute_value& upkeep)
void unit::write_upkeep(config::attribute_value& upkeep) const
{
upkeep = std::visit(upkeep_type_visitor{}, upkeep_);
upkeep = utils::visit(upkeep_type_visitor{}, upkeep_);
}
void unit::clear_changed_attributes()

View file

@ -21,7 +21,7 @@
#include "units/ptr.hpp"
#include "units/attack_type.hpp"
#include "units/race.hpp"
#include <variant>
#include "utils/variant.hpp"
#include <bitset>
@ -1173,10 +1173,13 @@ public:
static std::string type() { static std::string v = "loyal"; return v; }
};
using upkeep_t = std::variant<upkeep_full, upkeep_loyal, int>;
using upkeep_t = utils::variant<upkeep_full, upkeep_loyal, int>;
/** Visitor helper class to fetch the appropriate upkeep value. */
class upkeep_value_visitor
#ifdef USING_BOOST_VARIANT
: public boost::static_visitor<int>
#endif
{
public:
explicit upkeep_value_visitor(const unit& unit) : u_(unit) {}
@ -1204,6 +1207,9 @@ public:
/** Visitor helper struct to fetch the upkeep type flag if applicable, or the the value otherwise. */
struct upkeep_type_visitor
#ifdef USING_BOOST_VARIANT
: public boost::static_visitor<std::string>
#endif
{
template<typename T>
std::enable_if_t<!std::is_same_v<int, T>, std::string>
@ -1221,6 +1227,9 @@ public:
/** Visitor helper class to parse the upkeep value from a config. */
class upkeep_parser_visitor
#ifdef USING_BOOST_VARIANT
: public boost::static_visitor<upkeep_t>
#endif
{
public:
template<typename N>
@ -1239,7 +1248,7 @@ public:
throw std::invalid_argument(b.str());
}
upkeep_t operator()(std::monostate) const
upkeep_t operator()(utils::monostate) const
{
return upkeep_full();
}

48
src/utils/any.hpp Normal file
View file

@ -0,0 +1,48 @@
/*
Copyright (C) 2022 - 2024
Part of the Battle for Wesnoth Project https://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#pragma once
/**
* @file
*
* MacOS doesn't support std::any_cast when targing MacOS < 10.14 (currently we target 10.11).
* This provides a wrapper around the STL variant API on all platforms except MacOS, which
* instead utilizes boost::any.
*/
#ifdef __APPLE__
#define USING_BOOST_ANY
#endif
#ifndef USING_BOOST_ANY
#include <any>
#else
#include <boost/any.hpp>
#endif
namespace utils
{
#ifndef USING_BOOST_ANY
using std::any;
using std::any_cast;
#else
using boost::any;
using boost::any_cast;
#endif
} // namespace utils

89
src/utils/variant.hpp Normal file
View file

@ -0,0 +1,89 @@
/*
Copyright (C) 2021 - 2024
Part of the Battle for Wesnoth Project https://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#pragma once
/**
* @file
*
* MacOS doesn't support std::visit when targing MacOS < 10.14 (currently we target 10.11).
* This provides a wrapper around the STL variant API on all platforms except MacOS, which
* instead utilizes boost::variant.
*/
#ifdef __APPLE__
#define USING_BOOST_VARIANT
#endif
#ifndef USING_BOOST_VARIANT
#include <variant>
#else
#include <boost/variant.hpp>
#endif
namespace utils
{
#ifndef USING_BOOST_VARIANT
using std::get;
using std::get_if;
using std::holds_alternative;
using std::monostate;
using std::variant;
using std::visit;
#else
using boost::get;
using boost::variant;
using monostate = boost::blank;
template<typename... Args>
inline auto visit(Args&&... args)
{
return boost::apply_visitor(std::forward<Args>(args)...);
}
template<typename Ret, typename... Types>
inline bool holds_alternative(const boost::variant<Types...>& variant)
{
return boost::get<Ret>(&variant) != nullptr;
}
template<typename Ret, typename... Types>
inline Ret* get_if(boost::variant<Types...>* variant)
{
return boost::get<Ret>(variant);
}
template<typename Ret, typename... Types>
inline const Ret* get_if(const boost::variant<Types...>* variant)
{
return boost::get<Ret>(variant);
}
#endif
template<typename... Types>
std::size_t variant_index(const variant<Types...>& var)
{
#ifndef USING_BOOST_VARIANT
return var.index();
#else
return var.which();
#endif
}
} // namespace utils

View file

@ -329,6 +329,9 @@ bool vconfig::has_child(const std::string& key) const
namespace {
struct vconfig_expand_visitor
#ifdef USING_BOOST_VARIANT
: boost::static_visitor<void>
#endif
{
config::attribute_value &result;
const variable_set& vars;

View file

@ -121,7 +121,7 @@ wesnothd_connection::~wesnothd_connection()
{
MPTEST_LOG;
if(auto socket = std::get_if<tls_socket>(&socket_)) {
if(auto socket = utils::get_if<tls_socket>(&socket_)) {
error_code ec;
// this sends close_notify for secure connection shutdown
(*socket)->async_shutdown([](const error_code&) {} );
@ -143,7 +143,7 @@ void wesnothd_connection::handle_resolve(const error_code& ec, results_type resu
throw system_error(ec);
}
boost::asio::async_connect(*std::get<raw_socket>(socket_), results,
boost::asio::async_connect(*utils::get<raw_socket>(socket_), results,
std::bind(&wesnothd_connection::handle_connect, this, std::placeholders::_1, std::placeholders::_2));
}
@ -175,9 +175,9 @@ void wesnothd_connection::handshake()
static const uint32_t handshake = 0;
static const uint32_t tls_handshake = htonl(uint32_t(1));
boost::asio::async_write(*std::get<raw_socket>(socket_), boost::asio::buffer(use_tls_ ? reinterpret_cast<const char*>(&tls_handshake) : reinterpret_cast<const char*>(&handshake), 4),
boost::asio::async_write(*utils::get<raw_socket>(socket_), boost::asio::buffer(use_tls_ ? reinterpret_cast<const char*>(&tls_handshake) : reinterpret_cast<const char*>(&handshake), 4),
[](const error_code& ec, std::size_t) { if(ec) { throw system_error(ec); } });
boost::asio::async_read(*std::get<raw_socket>(socket_), boost::asio::buffer(reinterpret_cast<std::byte*>(&handshake_response_), 4),
boost::asio::async_read(*utils::get<raw_socket>(socket_), boost::asio::buffer(reinterpret_cast<std::byte*>(&handshake_response_), 4),
std::bind(&wesnothd_connection::handle_handshake, this, std::placeholders::_1));
}
@ -225,11 +225,11 @@ void wesnothd_connection::handle_handshake(const error_code& ec)
if(handshake_response_ == 0x00000000) {
network_asio::load_tls_root_certs(tls_context_);
raw_socket s { std::move(std::get<raw_socket>(socket_)) };
raw_socket s { std::move(utils::get<raw_socket>(socket_)) };
tls_socket ts { new tls_socket::element_type{std::move(*s), tls_context_} };
socket_ = std::move(ts);
auto& socket { *std::get<tls_socket>(socket_) };
auto& socket { *utils::get<tls_socket>(socket_) };
socket.set_verify_mode(
boost::asio::ssl::verify_peer |
@ -267,10 +267,10 @@ void wesnothd_connection::fallback_to_unencrypted()
assert(use_tls_ == true);
use_tls_ = false;
boost::asio::ip::tcp::endpoint endpoint { std::get<raw_socket>(socket_)->remote_endpoint() };
std::get<raw_socket>(socket_)->close();
boost::asio::ip::tcp::endpoint endpoint { utils::get<raw_socket>(socket_)->remote_endpoint() };
utils::get<raw_socket>(socket_)->close();
std::get<raw_socket>(socket_)->async_connect(endpoint,
utils::get<raw_socket>(socket_)->async_connect(endpoint,
std::bind(&wesnothd_connection::handle_connect, this, std::placeholders::_1, endpoint));
}
@ -343,7 +343,7 @@ void wesnothd_connection::send_data(const configr_of& request)
void wesnothd_connection::cancel()
{
MPTEST_LOG;
std::visit([](auto&& socket) {
utils::visit([](auto&& socket) {
if(socket->lowest_layer().is_open()) {
boost::system::error_code ec;
@ -506,7 +506,7 @@ void wesnothd_connection::send()
buf.data()
};
std::visit([this, &bufs](auto&& socket) {
utils::visit([this, &bufs](auto&& socket) {
boost::asio::async_write(*socket, bufs,
std::bind(&wesnothd_connection::is_write_complete, this, std::placeholders::_1, std::placeholders::_2),
std::bind(&wesnothd_connection::handle_write, this, std::placeholders::_1, std::placeholders::_2));
@ -518,7 +518,7 @@ void wesnothd_connection::recv()
{
MPTEST_LOG;
std::visit([this](auto&& socket) {
utils::visit([this](auto&& socket) {
boost::asio::async_read(*socket, read_buf_,
std::bind(&wesnothd_connection::is_read_complete, this, std::placeholders::_1, std::placeholders::_2),
std::bind(&wesnothd_connection::handle_read, this, std::placeholders::_1, std::placeholders::_2));
@ -572,21 +572,21 @@ bool wesnothd_connection::wait_and_receive_data(config& data)
void wesnothd_connection::set_keepalive(int seconds)
{
boost::asio::socket_base::keep_alive option(true);
std::get<raw_socket>(socket_)->set_option(option);
utils::get<raw_socket>(socket_)->set_option(option);
#ifdef __linux__
int timeout = 10;
int cnt = std::max((seconds - 10) / 10, 1);
int interval = 10;
setsockopt(std::get<raw_socket>(socket_)->native_handle(), SOL_TCP, TCP_KEEPIDLE, &timeout, sizeof(timeout));
setsockopt(std::get<raw_socket>(socket_)->native_handle(), SOL_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt));
setsockopt(std::get<raw_socket>(socket_)->native_handle(), SOL_TCP, TCP_KEEPINTVL, &interval, sizeof(interval));
setsockopt(utils::get<raw_socket>(socket_)->native_handle(), SOL_TCP, TCP_KEEPIDLE, &timeout, sizeof(timeout));
setsockopt(utils::get<raw_socket>(socket_)->native_handle(), SOL_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt));
setsockopt(utils::get<raw_socket>(socket_)->native_handle(), SOL_TCP, TCP_KEEPINTVL, &interval, sizeof(interval));
#elif defined(__APPLE__) && defined(__MACH__)
setsockopt(std::get<raw_socket>(socket_)->native_handle(), IPPROTO_TCP, TCP_KEEPALIVE, &seconds, sizeof(seconds));
setsockopt(utils::get<raw_socket>(socket_)->native_handle(), IPPROTO_TCP, TCP_KEEPALIVE, &seconds, sizeof(seconds));
#elif defined(_WIN32)
// these are in milliseconds for windows
DWORD timeout_ms = seconds * 1000;
setsockopt(std::get<raw_socket>(socket_)->native_handle(), SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<const char*>(&timeout_ms), sizeof(timeout_ms));
setsockopt(std::get<raw_socket>(socket_)->native_handle(), SOL_SOCKET, SO_SNDTIMEO, reinterpret_cast<const char*>(&timeout_ms), sizeof(timeout_ms));
setsockopt(utils::get<raw_socket>(socket_)->native_handle(), SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<const char*>(&timeout_ms), sizeof(timeout_ms));
setsockopt(utils::get<raw_socket>(socket_)->native_handle(), SOL_SOCKET, SO_SNDTIMEO, reinterpret_cast<const char*>(&timeout_ms), sizeof(timeout_ms));
#endif
}

View file

@ -95,7 +95,7 @@ public:
/** True if connection is currently using TLS and thus is allowed to send cleartext passwords or auth tokens */
bool using_tls() const
{
return std::holds_alternative<tls_socket>(socket_);
return utils::holds_alternative<tls_socket>(socket_);
}
void cancel();
@ -146,7 +146,7 @@ private:
std::string service_;
typedef std::unique_ptr<boost::asio::ip::tcp::socket> raw_socket;
typedef std::unique_ptr<boost::asio::ssl::stream<raw_socket::element_type>> tls_socket;
typedef std::variant<raw_socket, tls_socket> any_socket;
typedef utils::variant<raw_socket, tls_socket> any_socket;
bool use_tls_;
any_socket socket_;