#ifndef FUNCTION_H #define FUNCTION_H #include #include #include #include using namespace std; template class function : public map<_Key,_Tp> { public: function() { } virtual ~function() { } // This modifies the first argument instead of returning a value because we // don't know what type to return. For example, someone could pass something // which is of a class derived from function. friend void range_restrict(function<_Key, _Tp>& in_function, const set<_Tp>& in_range_set) { // We have to be careful deleting and incrementing iterators at the same // time. We could probably use remove_if, but I don't really have // experience with it... typename function<_Key,_Tp>::iterator a_mapping; for (a_mapping = in_function.begin(); a_mapping != in_function.end(); ) { if (in_range_set.find((*a_mapping).second) == in_range_set.end()) in_function.erase(a_mapping++); else ++a_mapping; } } // Overload () virtual const _Tp& operator()(const _Key& in_argument) const { // Function applied to value outside its domain if ( this->find(in_argument) == this->end() ) assert(false); return (this->find(in_argument))->second; } const set<_Key> domain() const { set<_Key> domain; typename function<_Key,_Tp>::const_iterator a_mapping; for (a_mapping = this->begin(); a_mapping != this->end(); a_mapping++) { domain.insert((*a_mapping).first); } return domain; } const set<_Tp> range() const { typename std::set<_Tp> range; typename function<_Key,_Tp>::const_iterator a_mapping; for (a_mapping = this->begin(); a_mapping != this->end(); a_mapping++) { range.insert((*a_mapping).second); } return range; } friend ostream& operator<< (ostream& in_ostream, const function<_Key,_Tp>& in_function) { in_ostream << "{" << endl; typename function<_Key,_Tp>::const_iterator a_mapping; for (a_mapping = in_function.begin(); a_mapping != in_function.end(); a_mapping++) { in_ostream << (*a_mapping).first << " -> " << (*a_mapping).second; typename function<_Key,_Tp>::const_iterator next_mapping(a_mapping); next_mapping++; if (next_mapping != in_function.end()) in_ostream << ","; in_ostream << endl; } in_ostream << "}"; return in_ostream; } }; #endif // FUNCTION_H