Add a generic contains() function...
...that detects if a container contains a given value. This will use std::find in most cases, but uses the member find() function when detecting if an associative container contains a key_value. So it should be efficient, while allowing more readable code. This function is in the util:: namespace to avoid any future naming conflicts.
This commit is contained in:
parent
43018403fe
commit
793d19b3a8
3 changed files with 49 additions and 39 deletions
|
@ -619,22 +619,6 @@ std::string find_recall_location(const int side, map_location& recall_location,
|
|||
}
|
||||
|
||||
namespace { // Helpers for check_recruit_location()
|
||||
/// Returns whether or not the value is found in the vector.
|
||||
template<typename T>
|
||||
inline bool contains(const std::vector<T> & container, const T & value)
|
||||
{
|
||||
typename std::vector<T>::const_iterator end = container.end();
|
||||
|
||||
return std::find(container.begin(), end, value) != end;
|
||||
}
|
||||
|
||||
/// Returns whether or not the value is found in the set.
|
||||
template<typename T>
|
||||
inline bool contains(const std::set<T> & container, const T & value)
|
||||
{
|
||||
return container.find(value) != container.end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if @a recruiter can recruit at @a preferred.
|
||||
* If @a unit_type is not empty, it must be in the unit-specific recruit list.
|
||||
|
@ -652,7 +636,7 @@ namespace { // Helpers for check_recruit_location()
|
|||
|
||||
if ( !unit_type.empty() ) {
|
||||
// Make sure the specified type is in the unit's recruit list.
|
||||
if ( !contains(recruiter.recruits(), unit_type) )
|
||||
if ( !util::contains(recruiter.recruits(), unit_type) )
|
||||
return RECRUIT_NO_ABLE_LEADER;
|
||||
}
|
||||
|
||||
|
@ -691,7 +675,7 @@ RECRUIT_CHECK check_recruit_location(const int side, map_location &recruit_locat
|
|||
|
||||
// If the specified unit type is in the team's recruit list, there is no
|
||||
// need to check each leader's list.
|
||||
if ( contains((*resources::teams)[side-1].recruits(), unit_type) )
|
||||
if ( util::contains((*resources::teams)[side-1].recruits(), unit_type) )
|
||||
check_type.clear();
|
||||
|
||||
// If the check location is not valid, we will never get an "OK" result.
|
||||
|
|
|
@ -51,15 +51,6 @@ void copy_keys(config& out,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//helper function
|
||||
inline bool contains(const std::vector<std::string>& container,
|
||||
const std::string& value)
|
||||
{
|
||||
return std::find(container.begin(), container.end(), value)
|
||||
!= container.end();
|
||||
}
|
||||
|
||||
} //anonymous namespace
|
||||
|
||||
namespace mp
|
||||
|
@ -190,7 +181,7 @@ std::vector<std::string> manager::get_required_not_enabled(const elem& e) const
|
|||
std::vector<std::string> result;
|
||||
|
||||
BOOST_FOREACH (std::string str, required) {
|
||||
if (!contains(mods_, str)) {
|
||||
if ( !util::contains(mods_, str) ) {
|
||||
result.push_back(str);
|
||||
}
|
||||
}
|
||||
|
@ -231,7 +222,7 @@ bool manager::conflicts(const elem& elem1, const elem& elem2, bool directonly) c
|
|||
std::vector<std::string> ignored =
|
||||
utils::split(data1["ignore_incompatible_" + elem2.type]);
|
||||
|
||||
if (contains(ignored, elem2.id)) {
|
||||
if ( util::contains(ignored, elem2.id) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -240,7 +231,7 @@ bool manager::conflicts(const elem& elem1, const elem& elem2, bool directonly) c
|
|||
std::vector<std::string> ignored =
|
||||
utils::split(data2["ignore_incompatible_" + elem1.type]);
|
||||
|
||||
if (contains(ignored, elem1.id)) {
|
||||
if ( util::contains(ignored, elem1.id) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -252,24 +243,24 @@ bool manager::conflicts(const elem& elem1, const elem& elem2, bool directonly) c
|
|||
std::vector<std::string> allowed =
|
||||
utils::split(data1["allow_" + elem2.type]);
|
||||
|
||||
result = !contains(allowed, elem2.id) && !requires(elem1, elem2);
|
||||
result = !util::contains(allowed, elem2.id) && !requires(elem1, elem2);
|
||||
} else if (data1.has_attribute("disallow_" + elem2.type)) {
|
||||
std::vector<std::string> disallowed =
|
||||
utils::split(data1["disallow_" + elem2.type]);
|
||||
|
||||
result = contains(disallowed, elem2.id);
|
||||
result = util::contains(disallowed, elem2.id);
|
||||
}
|
||||
|
||||
if (data2.has_attribute("allow_" + elem1.type)) {
|
||||
std::vector<std::string> allowed =
|
||||
utils::split(data2["allow_" + elem1.type]);
|
||||
|
||||
result = result || (!contains(allowed, elem1.id) && !requires(elem2, elem1));
|
||||
result = result || (!util::contains(allowed, elem1.id) && !requires(elem2, elem1));
|
||||
} else if (data2.has_attribute("disallow_" + elem1.type)) {
|
||||
std::vector<std::string> disallowed =
|
||||
utils::split(data2["disallow_" + elem1.type]);
|
||||
|
||||
result = result || contains(disallowed, elem1.id);
|
||||
result = result || util::contains(disallowed, elem1.id);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
|
@ -326,7 +317,7 @@ bool manager::requires(const elem& elem1, const elem& elem2) const
|
|||
std::vector<std::string> required =
|
||||
utils::split(data["force_modification"]);
|
||||
|
||||
return contains(required, elem2.id);
|
||||
return util::contains(required, elem2.id);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -523,7 +514,7 @@ bool manager::change_scenario(const std::string& id)
|
|||
|
||||
std::vector<std::string> newmods = req;
|
||||
BOOST_FOREACH (const std::string& i, mods_) {
|
||||
if (!contains(con, i)) {
|
||||
if ( !util::contains(con, i) ) {
|
||||
newmods.push_back(i);
|
||||
}
|
||||
}
|
||||
|
@ -593,7 +584,7 @@ bool manager::change_era(const std::string& id)
|
|||
|
||||
std::vector<std::string> newmods = req;
|
||||
BOOST_FOREACH (const std::string& i, mods_) {
|
||||
if (!contains(con, i)) {
|
||||
if ( !util::contains(con, i) ) {
|
||||
newmods.push_back(i);
|
||||
}
|
||||
}
|
||||
|
@ -666,7 +657,7 @@ bool manager::change_modifications
|
|||
}
|
||||
}
|
||||
|
||||
if (!contains(compatible, era_)) {
|
||||
if ( !util::contains(compatible, era_) ) {
|
||||
if (!compatible.empty()) {
|
||||
era_ = change_era_dialog(compatible);
|
||||
} else {
|
||||
|
@ -703,7 +694,7 @@ bool manager::change_modifications
|
|||
}
|
||||
}
|
||||
|
||||
if (!contains(compatible, scenario_)) {
|
||||
if ( !util::contains(compatible, scenario_) ) {
|
||||
if (!compatible.empty()) {
|
||||
scenario_ = change_scenario_dialog(compatible);
|
||||
} else {
|
||||
|
|
35
src/util.hpp
35
src/util.hpp
|
@ -241,8 +241,43 @@ public:
|
|||
T &operator*() const { return *ptr_; }
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
/// A struct that exists to implement a generic wrapper for std::find.
|
||||
/// Container should "look like" an STL container of Values.
|
||||
template<typename Container, typename Value> struct contains_impl {
|
||||
static bool eval(const Container & container, const Value & value)
|
||||
{
|
||||
typename Container::const_iterator end = container.end();
|
||||
return std::find(container.begin(), end, value) != end;
|
||||
}
|
||||
};
|
||||
/// A struct that exists to implement a generic wrapper for the find()
|
||||
/// member of associative containers.
|
||||
/// Container should "look like" an STL associative container.
|
||||
template<typename Container>
|
||||
struct contains_impl<Container, typename Container::key_type> {
|
||||
static bool eval(const Container & container,
|
||||
const typename Container::key_type & value)
|
||||
{
|
||||
return container.find(value) != container.end();
|
||||
}
|
||||
};
|
||||
}//namespace detail
|
||||
|
||||
/// Returns true iff @a value is found in @a container.
|
||||
/// This should work whenever Container "looks like" an STL container of Values.
|
||||
/// Normally this uses std::find(), but a simulated partial template specialization
|
||||
/// exists when Value is Container::key_type. In this case, Container is assumed
|
||||
/// an associative container, and the member function find() is used.
|
||||
template<typename Container, typename Value>
|
||||
inline bool contains(const Container & container, const Value & value)
|
||||
{
|
||||
return detail::contains_impl<Container, Value>::eval(container, value);
|
||||
}
|
||||
|
||||
}//namespace util
|
||||
|
||||
|
||||
#if 1
|
||||
# include <SDL_types.h>
|
||||
typedef Sint32 fixed_t;
|
||||
|
|
Loading…
Add table
Reference in a new issue