[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi] Difficulty writing a generic contains() function template
From: |
Greg Chicares |
Subject: |
[lmi] Difficulty writing a generic contains() function template |
Date: |
Tue, 04 May 2010 17:08:08 +0000 |
User-agent: |
Thunderbird 2.0.0.24 (Windows/20100228) |
I'm stuck here ['icon_monger.cpp', line 45]:
// SOMEDAY !! Write a "contains.hpp" header that implements this
// function for every standard container as well as std::string.
// Rationale: this usage represents half of our find() calls, and
// the idiom is verbose.
template<typename Key, typename Compare, typename Allocator>
bool contains(std::set<Key,Compare,Allocator> const& c, Key const& k)
{
return c.end() != c.find(k);
}
What's the best way to proceed?
I could write one such function for each container, but that's tasteless.
I thought the following was clever, until I added std::set to the unit
test and realized std::set::key_type is the same as std::set::value_type.
#include <algorithm> // std::find()
#include <cassert>
#include <map>
#include <set>
#include <string>
#include <vector>
// If a class has 'npos', assume it should behave like std::string.
template<typename T>
bool contains(T const& container, T const& element, typename T::size_type =
T::npos)
{
return T::npos != container.find(element);
}
template<typename T>
bool contains(T const& container, typename T::traits_type::char_type const*
element)
{
return T::npos != container.find(element);
}
// If a class has 'key_type', assume it should behave like an associative
container.
template<typename T>
bool contains(T const& container, typename T::key_type const& element)
{
return container.end() != container.find(element);
}
// Otherwise, std::find() is the best we can do.
template<typename T>
bool contains(T const& container, typename T::value_type const& element)
{
return container.end() != std::find(container.begin(), container.end(),
element);
}
int main()
{
std::string s("etaoin shrdlu");
std::string t("alpha omega");
assert( contains(s, s));
assert(!contains(s, t));
assert( contains(s, "eta"));
assert(!contains(s, "epsilon"));
#if 1 // It compiles if I change this to '#if 0'...
std::set<std::string> u;
u.insert("one");
assert( contains(u, "one"));
assert(!contains(u, "two"));
#endif // 1
std::map<std::string, int> m;
m["one"] = 1;
assert( contains(m, "one"));
assert(!contains(m, "two"));
std::vector<double> v;
v.push_back(3.14);
assert( contains(v, 3.14));
assert(!contains(v, 0.00));
}
- [lmi] Difficulty writing a generic contains() function template,
Greg Chicares <=