register
[username]

Dual Predicate Map

jul, 2008

problem:

Sorts with one predicate and Finds with another. Useful for partial matching

solution:

template class
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);
}
instanciation
Where LessThan and LessThanL are you own predicates (see below)
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");
predicate examples
Note that in windows strcasecmp is different (stricmp) and you should use a MACRO for this function.
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;}
};

tags:

Visual C++; c++; partial match; dual predicate; sort; find