/*
* bag: T -> N bag
* (C) Porkolab Zoltan, ELTE, Budapest, Hungary
* (C) 2001
*/
#include <list>
#include <algorithm>
template <class T>
class bad_value
{
public:
bad_value( const T& t) : m_value(t) { }
T value() { return m_value; }
private:
T m_value;
};
template <class T>
class bag
{
public:
void put( const T& t);
bool remove( const T& t);
bool remove_all( const T& t);
int mul( const T& t) const;
int operator[]( const T& t) const;
private:
struct my_pair
{
my_pair(T f, int s) : first(f), second(s) { }
T first;
int second;
int operator==(const my_pair& x) const { return first == x.first; }
};
std::list<my_pair> lst;
};
template <class T>
int bag<T>::mul( const T& t) const
{
my_pair mp(t,1);
typename std::list<my_pair>::const_iterator ci =
find(lst.begin(), lst.end(), mp);
return ci == lst.end() ? 0 : ci->second;
}
template <class T>
void bag<T>::put( const T& t)
{
my_pair mp(t,1);
typename std::list<my_pair>::iterator ci =
find(lst.begin(), lst.end(), mp);
if ( ci == lst.end() )
{
lst.push_back(mp);
}
else
{
++ ci->second;
}
}
template <class T>
bool bag<T>::remove( const T& t)
{
my_pair mp(t,1);
typename std::list<my_pair>::iterator ci =
find(lst.begin(), lst.end(), mp);
if ( ci != lst.end() )
{
if( 0 == -- ci->second )
lst.erase(ci);
return true;
}
return false;
}
template <class T>
bool bag<T>::remove_all( const T& t)
{
my_pair mp(t,1);
typename std::list<my_pair>::iterator ci =
find(lst.begin(), lst.end(), mp);
if ( ci != lst.end() )
{
lst.erase(ci);
return true;
}
return false;
}
template <class T>
int bag<T>::operator[]( const T& t) const
{
if( int i = mul(t) )
return i;
else
throw bad_value<long>(t);
}