Dual Predicate Map
jul, 2008
problem:
Sorts with one predicate and Finds with another. Useful for partial matching
solution:
Note that ANSI C++ requires that the entire template be available to every compilation unit (ODR rule). So: DO NOT put the functions in a separate .cpp file and expect the compiler to be able to find them. The best source code organisation is to include the whole template in a header file and include that everywhere that it is required. export is not supported for all compilers.
template<class KeyType, class SortPred, class FindPred> class DualPred {
bool m_finding;
SortPred m_sp;
FindPred m_fp;
public:
DualPred(): m_finding(false) {}
void finding(const bool _finding) {m_finding = _finding;}
bool operator() (KeyType k1, KeyType k2) const;
};
template<class KeyType, class ValueType, class SortPred, class FindPred>
class DualPredMap: public map<KeyType, ValueType, DualPred<KeyType, SortPred, FindPred> > {
public:
DualPredMap(): map<KeyType, ValueType, DualPred<KeyType, SortPred, FindPred> >::map() {}
typename DualPredMap<KeyType, ValueType, SortPred, FindPred>::iterator find(KeyType haystack);
};
template<class KeyType, class ValueType, class SortPred, class FindPred>
typename DualPredMap<KeyType, ValueType, SortPred, FindPred>::iterator
DualPredMap<KeyType, ValueType, SortPred, FindPred>::find(KeyType k)
{
//not thread safe part: do NOT insert anything into the map at this point
//or implement a mutex
key_comp().finding(true);
typename DualPredMap<KeyType, ValueType, SortPred, FindPred>::iterator i = map<KeyType, ValueType, DualPred<KeyType, SortPred, FindPred> >::find(k);
key_comp().finding(false);
return i;
}
template<class KeyType, class SortPred, class FindPred>
bool DualPred<KeyType, SortPred, FindPred>::operator() (KeyType k1, KeyType k2) const
{
if (m_finding)
return m_fp(k1, k2);
else
return m_sp(k1, k2);
}
DualPred<const char*, int, LessThan, LessThanL> dp;
DualPred<const char*, int, LessThan, LessThanL>::iterator i;
dp.insert(make_pair<const char*, int>("example", 3));
i = dp.find("example");
class LessThan {
public:
bool operator() (const char *str1, const char *str2) const {return strcmp(str1, str2) < 0;}
};
class LessThanCI {
public:
bool operator() (const char *str1, const char *str2) const {return strcasecmp(str1, str2) < 0;}
};