This commit is contained in:
Chris Beck 2014-11-11 15:48:21 -05:00
commit 9fdc91e8a9
4 changed files with 96 additions and 104 deletions

View file

@ -96,6 +96,8 @@
#include <boost/bind.hpp> // for bind_t, bind
#include <boost/foreach.hpp> // for auto_any_base, etc
#include <boost/intrusive_ptr.hpp> // for intrusive_ptr
#include <boost/range/algorithm.hpp> // boost::copy
#include <boost/range/adaptors.hpp> // boost::adaptors::filtered
#include <boost/tuple/tuple.hpp> // for tuple
#include <cassert> // for assert
#include <cstring> // for strcmp, NULL
@ -1586,11 +1588,9 @@ static int intf_find_reach(lua_State *L)
return 1;
}
#ifdef HAVE_CXX11
static bool intf_find_cost_map_helper(const unit * ptr) {
return ptr->get_location().valid();
}
#endif
/**
* Is called with one or more units and builds a cost map.
@ -1618,18 +1618,7 @@ static int intf_find_cost_map(lua_State *L)
}
else if (!filter.null()) // 1. arg - filter
{
const unit_filter ufilt(filter, resources::filter_con);
#ifdef HAVE_CXX11
std::vector<const unit *> matches = ufilt.all_matches_on_map();
std::copy_if(matches.begin(), matches.end(), std::back_inserter(real_units), &intf_find_cost_map_helper);
#else
BOOST_FOREACH(const unit * u, ufilt.all_matches_on_map()) {
if (u->get_location().valid()) {
real_units.push_back(u);
}
}
#endif
boost::copy(unit_filter(filter, resources::filter_con).all_matches_on_map() | boost::adaptors::filtered(&intf_find_cost_map_helper), std::back_inserter(real_units));
}
else // 1. + 2. arg - coordinates
{

View file

@ -24,7 +24,7 @@
#include <stdexcept>
using namespace variable_info_3_detail;
using namespace variable_info_detail;
/// general helpers
namespace
@ -50,7 +50,7 @@ namespace
}
}
template<const variable_info_3_type vit>
template<const variable_info_type vit>
typename maybe_const<vit, config>::type& get_child_at(typename maybe_const<vit, config>::type& cfg, const std::string& key, int index = 0);
template<>
@ -132,12 +132,12 @@ namespace
throw std::range_error("Failed to convert the TVisitor::param_type type");
}
template <const variable_info_3_type vit, typename TResult>
template <const variable_info_type vit, typename TResult>
class variable_info_visitor
{
public:
typedef TResult result_type;
typedef variable_info_3_state<vit>& param_type;
typedef variable_info_state<vit>& param_type;
#define DEFAULTHANDLER(name) result_type name(param_type) const { throw invalid_variablename_exception(); }
DEFAULTHANDLER(from_start)
DEFAULTHANDLER(from_named)
@ -146,12 +146,12 @@ namespace
#undef DEFAULTHANDLER
};
template <const variable_info_3_type vit, typename TResult>
template <const variable_info_type vit, typename TResult>
class variable_info_visitor_const
{
public:
typedef TResult result_type;
typedef const variable_info_3_state<vit>& param_type;
typedef const variable_info_state<vit>& param_type;
#define DEFAULTHANDLER(name) result_type name(param_type) const { throw invalid_variablename_exception(); }
DEFAULTHANDLER(from_start)
DEFAULTHANDLER(from_named)
@ -181,7 +181,7 @@ namespace
}
/// Adds a '.<key>' to the current variable
template<const variable_info_3_type vit>
template<const variable_info_type vit>
class get_variable_key_visitor
: public variable_info_visitor<vit, void>
{
@ -221,7 +221,7 @@ namespace
/// appens a [index] to the variable.
/// we only support from_named since [index][index2] or a.length[index] both doesn't make sense.
template<const variable_info_3_type vit>
template<const variable_info_type vit>
class get_variable_index_visitor
: public variable_info_visitor<vit, void>
{
@ -241,7 +241,7 @@ namespace
namespace
{
///tries to convert it to an (maybe const) attribute value
template<const variable_info_3_type vit>
template<const variable_info_type vit>
class as_skalar_visitor
: public variable_info_visitor_const<vit, typename maybe_const<vit, config::attribute_value>::type&>
{
@ -274,7 +274,7 @@ namespace
/// tries to convert to a (const) config&, unlike range based operation this also supports 'from_start'
/// Note: Currently getting the 'from_start' case here is impossible, becasue we always apply at least one string key.
template<const variable_info_3_type vit>
template<const variable_info_type vit>
class as_container_visitor
: public variable_info_visitor_const<vit, typename maybe_const<vit, config>::type&>
{
@ -296,8 +296,9 @@ namespace
/// range_based operations
namespace {
template<const variable_info_3_type vit, typename THandler>
// as_range_visitor_base wants to partially specialize from_indexed but nothing else
// so we put everything else in this base class which is common for both as_range_visitor_base versions.
template<const variable_info_type vit, typename THandler>
class as_range_visitor_base2
: public variable_info_visitor_const<vit, typename THandler::result_type>
{
@ -307,28 +308,30 @@ namespace {
{
return handler_(*state.child_, state.key_, 0, state.child_->child_count(state.key_));
}
typename as_range_visitor_base2::result_type from_indexed(typename as_range_visitor_base2::param_type state) const
{
//Ensure we have a config at the given explicit position.
get_child_at<vit>(*state.child_, state.key_, state.index_);
return this->handler_(*state.child_, state.key_, state.index_, state.index_ + 1);
}
protected:
const THandler& handler_;
};
template<const variable_info_3_type vit, typename THandler>
/// @param THandler a function
/// ( (const-) config& cfg, const std::string& name, int range_begin, int range_end) -> THandler::result_type
/// that does the actual work on the range of children of cfg with name name.
template<const variable_info_type vit, typename THandler>
class as_range_visitor_base
: public as_range_visitor_base2<vit, THandler>
{
public:
as_range_visitor_base(const THandler& handler) : as_range_visitor_base2<vit, THandler>(handler) {}
//inherit all from as_range_visitor_base2
typename as_range_visitor_base::result_type from_indexed(typename as_range_visitor_base::param_type state) const
{
//Ensure we have a config at the given explicit position.
get_child_at<vit>(*state.child_, state.key_, state.index_);
return this->handler_(*state.child_, state.key_, state.index_, state.index_ + 1);
}
};
const config non_empty_const_cfg = config_of("_", config());
//we cannot partly specialise methods so we are using inheritance.
template<typename THandler>
class as_range_visitor_base<vit_const, THandler>
: public as_range_visitor_base2<vit_const, THandler>
@ -347,7 +350,7 @@ namespace {
}
};
template<const variable_info_3_type vit>
template<const variable_info_type vit>
class variable_as_array_h
{
public:
@ -452,7 +455,7 @@ namespace {
/// misc
namespace
{
template<const variable_info_3_type vit>
template<const variable_info_type vit>
class clear_value_visitor
: public variable_info_visitor_const<vit, void>
{
@ -474,7 +477,7 @@ namespace
bool only_tables_;
};
template<const variable_info_3_type vit>
template<const variable_info_type vit>
class exists_as_container_visitor
: public variable_info_visitor_const<vit, bool>
{
@ -498,8 +501,8 @@ namespace
};
}
template<const variable_info_3_type vit>
variable_info_3<vit>::variable_info_3(const std::string& varname, t_config& vars)
template<const variable_info_type vit>
variable_info<vit>::variable_info(const std::string& varname, t_config& vars)
: name_(varname)
, state_(vars)
, valid_(true)
@ -514,13 +517,13 @@ variable_info_3<vit>::variable_info_3(const std::string& varname, t_config& vars
}
}
template<const variable_info_3_type vit>
variable_info_3<vit>::~variable_info_3()
template<const variable_info_type vit>
variable_info<vit>::~variable_info()
{
}
template<const variable_info_3_type vit>
void variable_info_3<vit>::calculate_value()
template<const variable_info_type vit>
void variable_info<vit>::calculate_value()
{
// this->state_ is initialized in the constructor.
size_t previous_index = 0;
@ -563,36 +566,36 @@ void variable_info_3<vit>::calculate_value()
}
}
template<const variable_info_3_type vit>
bool variable_info_3<vit>::explicit_index() const
template<const variable_info_type vit>
bool variable_info<vit>::explicit_index() const
{
throw_on_invalid();
return this->state_.type_ == state_start || this->state_.type_ == state_indexed;
}
template<const variable_info_3_type vit>
typename maybe_const<vit, config::attribute_value>::type& variable_info_3<vit>::as_scalar() const
template<const variable_info_type vit>
typename maybe_const<vit, config::attribute_value>::type& variable_info<vit>::as_scalar() const
{
throw_on_invalid();
return apply_visitor(as_skalar_visitor<vit>(), this->state_);
}
template<const variable_info_3_type vit>
typename maybe_const<vit, config>::type& variable_info_3<vit>::as_container() const
template<const variable_info_type vit>
typename maybe_const<vit, config>::type& variable_info<vit>::as_container() const
{
throw_on_invalid();
return apply_visitor(as_container_visitor<vit>(), this->state_);
}
template<const variable_info_3_type vit>
typename maybe_const<vit, config::child_itors>::type variable_info_3<vit>::as_array() const
template<const variable_info_type vit>
typename maybe_const<vit, config::child_itors>::type variable_info<vit>::as_array() const
{
throw_on_invalid();
return apply_visitor(as_range_visitor_base<vit,variable_as_array_h<vit> >(variable_as_array_h<vit>()), this->state_);
}
template<const variable_info_3_type vit>
void variable_info_3<vit>::throw_on_invalid() const
template<const variable_info_type vit>
void variable_info<vit>::throw_on_invalid() const
{
if(!this->valid_)
{
@ -601,74 +604,74 @@ void variable_info_3<vit>::throw_on_invalid() const
}
template<>
std::string variable_info_3<vit_const>::get_error_message() const
std::string variable_info<vit_const>::get_error_message() const
{
return "Cannot resolve variablename '" + this->name_ + "' for reading.";
}
template<>
std::string variable_info_3<vit_create_if_not_existent>::get_error_message() const
std::string variable_info<vit_create_if_not_existent>::get_error_message() const
{
return "Cannot resolve variablename '" + this->name_ + "' for writing.";
}
template<>
std::string variable_info_3<vit_throw_if_not_existent>::get_error_message() const
std::string variable_info<vit_throw_if_not_existent>::get_error_message() const
{
return "Cannot resolve variablename '" + this->name_ + "' for writing without creating new childs.";
}
template<const variable_info_3_type vit>
void non_const_variable_info_3<vit>::clear(bool only_tables) const
template<const variable_info_type vit>
void non_const_variable_info<vit>::clear(bool only_tables) const
{
this->throw_on_invalid();
return apply_visitor(clear_value_visitor<vit>(only_tables), this->state_);
}
template<const variable_info_3_type vit>
config::child_itors non_const_variable_info_3<vit>::append_array(std::vector<config> childs) const
template<const variable_info_type vit>
config::child_itors non_const_variable_info<vit>::append_array(std::vector<config> childs) const
{
this->throw_on_invalid();
return apply_visitor(as_range_visitor_base<vit,append_range_h>(append_range_h(childs)), this->state_);
}
template<const variable_info_3_type vit>
config::child_itors non_const_variable_info_3<vit>::insert_array(std::vector<config> childs) const
template<const variable_info_type vit>
config::child_itors non_const_variable_info<vit>::insert_array(std::vector<config> childs) const
{
this->throw_on_invalid();
return apply_visitor(as_range_visitor_base<vit,insert_range_h>(insert_range_h(childs)), this->state_);
}
template<const variable_info_3_type vit>
config::child_itors non_const_variable_info_3<vit>::replace_array(std::vector<config> childs) const
template<const variable_info_type vit>
config::child_itors non_const_variable_info<vit>::replace_array(std::vector<config> childs) const
{
this->throw_on_invalid();
return apply_visitor(as_range_visitor_base<vit,replace_range_h>(replace_range_h(childs)), this->state_);
}
template<const variable_info_3_type vit>
void non_const_variable_info_3<vit>::merge_array(std::vector<config> childs) const
template<const variable_info_type vit>
void non_const_variable_info<vit>::merge_array(std::vector<config> childs) const
{
this->throw_on_invalid();
apply_visitor(as_range_visitor_base<vit,merge_range_h>(merge_range_h(childs)), this->state_);
}
template<const variable_info_3_type vit>
bool variable_info_3<vit>::exists_as_attribute() const
template<const variable_info_type vit>
bool variable_info<vit>::exists_as_attribute() const
{
this->throw_on_invalid();
return (this->state_.type_ == state_temporary) || ((this->state_.type_ == state_named) && this->state_.child_->has_attribute(this->state_.key_));
}
template<const variable_info_3_type vit>
bool variable_info_3<vit>::exists_as_container() const
template<const variable_info_type vit>
bool variable_info<vit>::exists_as_container() const
{
this->throw_on_invalid();
return apply_visitor(exists_as_container_visitor<vit>(), this->state_);
}
///explicit instantiations
template class variable_info_3<vit_const>;
template class variable_info_3<vit_create_if_not_existent>;
template class variable_info_3<vit_throw_if_not_existent>;
template class non_const_variable_info_3<vit_create_if_not_existent>;
template class non_const_variable_info_3<vit_throw_if_not_existent>;
template class variable_info<vit_const>;
template class variable_info<vit_create_if_not_existent>;
template class variable_info<vit_throw_if_not_existent>;
template class non_const_variable_info<vit_create_if_not_existent>;
template class non_const_variable_info<vit_throw_if_not_existent>;

View file

@ -32,15 +32,15 @@ public:
}
};
template<const variable_info_3_detail::variable_info_3_type vit>
class variable_info_3
template<const variable_info_detail::variable_info_type vit>
class variable_info
{
public:
typedef typename variable_info_3_detail::maybe_const<vit,config>::type t_config;
typedef typename variable_info_detail::maybe_const<vit,config>::type t_config;
/// Doesn't throw
variable_info_3(const std::string& varname, t_config& vars);
~variable_info_3();
variable_info(const std::string& varname, t_config& vars);
~variable_info();
std::string get_error_message() const;
/// Doesn't throw
bool explicit_index() const;
@ -54,27 +54,27 @@ public:
NOTE:
If vit == vit_const, then the lifime of the returned const attribute_value& might end with the lifetime of this object.
*/
typename variable_info_3_detail::maybe_const<vit, config::attribute_value>::type &as_scalar() const;
typename variable_info_detail::maybe_const<vit, config::attribute_value>::type &as_scalar() const;
/// might throw invalid_variablename_exception
typename variable_info_3_detail::maybe_const<vit, config>::type & as_container() const;
typename variable_info_detail::maybe_const<vit, config>::type & as_container() const;
/// might throw invalid_variablename_exception
typename variable_info_3_detail::maybe_const<vit, config::child_itors>::type as_array() const; //range may be empty
typename variable_info_detail::maybe_const<vit, config::child_itors>::type as_array() const; //range may be empty
protected:
std::string name_;
variable_info_3_detail::variable_info_3_state<vit> state_;
variable_info_detail::variable_info_state<vit> state_;
void throw_on_invalid() const;
bool valid_;
void calculate_value();
};
/// Extends variable_info_3 with methods that can only be applied if vit != vit_const
template<const variable_info_3_detail::variable_info_3_type vit>
class non_const_variable_info_3 : public variable_info_3<vit>, variable_info_3_detail::enable_if_non_const<vit>::type
/// Extends variable_info with methods that can only be applied if vit != vit_const
template<const variable_info_detail::variable_info_type vit>
class non_const_variable_info : public variable_info<vit>, variable_info_detail::enable_if_non_const<vit>::type
{
public:
non_const_variable_info_3(const std::string& name, config& game_vars) : variable_info_3<vit>(name, game_vars) {}
~non_const_variable_info_3() {}
non_const_variable_info(const std::string& name, config& game_vars) : variable_info<vit>(name, game_vars) {}
~non_const_variable_info() {}
/// clears the vale this object points to
/// if only_tables = true it will not clear attribute values.
@ -102,15 +102,15 @@ public:
/**
this variable accessor will create a childtable when resolving name if it doesnt exist yet.
*/
typedef non_const_variable_info_3<variable_info_3_detail::vit_create_if_not_existent> variable_access_create;
typedef non_const_variable_info<variable_info_detail::vit_create_if_not_existent> variable_access_create;
/**
this variable accessor will throw an exception when trying to access a non existent table.
Note that the other types can throw too if name is invlid like '..[[[a'.
*/
typedef non_const_variable_info_3<variable_info_3_detail::vit_throw_if_not_existent> variable_access_throw;
typedef non_const_variable_info<variable_info_detail::vit_throw_if_not_existent> variable_access_throw;
/**
this variable accessor is takes a const reference and is guaranteed to not change the config.
*/
typedef variable_info_3<variable_info_3_detail::vit_const> variable_access_const;
typedef variable_info<variable_info_detail::vit_const> variable_access_const;
#endif

View file

@ -19,12 +19,12 @@
#include <string>
#include "config.hpp"
namespace variable_info_3_detail
namespace variable_info_detail
{
enum variable_info_3_type {vit_const, vit_create_if_not_existent, vit_throw_if_not_existent, };
enum variable_info_3_state_type {
enum variable_info_type {vit_const, vit_create_if_not_existent, vit_throw_if_not_existent, };
enum variable_info_state_type {
state_start = 0, // for internal use
// only used at the 'starting_pos' of the variable_info_3::calculate_value algorithm
// only used at the 'starting_pos' of the variable_info::calculate_value algorithm
state_named, // the result of .someval this can eigher man an attribute value or an
// child range
state_indexed, // the result of .someval[index] this is never an attribute value,
@ -34,7 +34,7 @@ namespace variable_info_3_detail
};
//Special case of boost::enable_if
template<const variable_info_3_type vit>
template<const variable_info_type vit>
struct enable_if_non_const
{
typedef enable_if_non_const<vit> type;
@ -45,7 +45,7 @@ namespace variable_info_3_detail
{
};
template<const variable_info_3_type vit, typename T>
template<const variable_info_type vit, typename T>
struct maybe_const
{
typedef T type;
@ -64,12 +64,12 @@ namespace variable_info_3_detail
};
template<const variable_info_3_type vit>
struct variable_info_3_state
template<const variable_info_type vit>
struct variable_info_state
{
typedef typename maybe_const<vit,config>::type t_child;
variable_info_3_state(t_child& vars)
variable_info_state(t_child& vars)
: child_(&vars)
, key_()
, index_(0)
@ -89,8 +89,8 @@ namespace variable_info_3_detail
// Then we store the result here.
config::attribute_value temp_val_;
// See the definition of 'variable_info_3_state_type'
variable_info_3_state_type type_;
// See the definition of 'variable_info_state_type'
variable_info_state_type type_;
};
}