/* -*- C++ -*- * lemon/maps.h - Part of LEMON, a generic C++ optimization library * * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport * (Egervary Research Group on Combinatorial Optimization, EGRES). * * Permission to use, modify and distribute this software is granted * provided that this copyright notice appears in all copies. For * precise terms see the accompanying LICENSE file. * * This software is provided "AS IS" with no warranty of any kind, * express or implied, and with no claim as to its suitability for any * purpose. * */ #ifndef LEMON_MAPS_H #define LEMON_MAPS_H #include #include ///\file ///\ingroup maps ///\brief Miscellaneous property maps /// ///\todo This file has the same name as the concept file in concept/, /// and this is not easily detectable in docs... #include namespace lemon { /// \addtogroup maps /// @{ /// Base class of maps. /// Base class of maps. /// It provides the necessary typedefs required by the map concept. template class MapBase { public: /// \e typedef _NeedCopy NeedCopy; ///\e typedef K Key; ///\e typedef T Value; }; /// Null map. (a.k.a. DoNothingMap) /// If you have to provide a map only for its type definitions, /// or if you have to provide a writable map, but /// data written to it will sent to /dev/null... template class NullMap : public MapBase { public: typedef MapBase Parent; typedef typename Parent::Key Key; typedef typename Parent::Value Value; /// Gives back a default constructed element. T operator[](const K&) const { return T(); } /// Absorbs the value. void set(const K&, const T&) {} }; template NullMap nullMap() { return NullMap(); } /// Constant map. /// This is a readable map which assigns a specified value to each key. /// In other aspects it is equivalent to the \ref NullMap. /// \todo set could be used to set the value. template class ConstMap : public MapBase { private: T v; public: typedef MapBase Parent; typedef typename Parent::Key Key; typedef typename Parent::Value Value; /// Default constructor /// The value of the map will be uninitialized. /// (More exactly it will be default constructed.) ConstMap() {} ///\e /// \param _v The initial value of the map. /// ConstMap(const T &_v) : v(_v) {} T operator[](const K&) const { return v; } void set(const K&, const T&) {} template struct rebind { typedef ConstMap other; }; template ConstMap(const ConstMap &, const T &_v) : v(_v) {} }; ///Returns a \ref ConstMap class ///This function just returns a \ref ConstMap class. ///\relates ConstMap template inline ConstMap constMap(const V &v) { return ConstMap(v); } //\todo to document later template struct Const { }; //\todo to document later template class ConstMap, NC > : public MapBase { public: typedef MapBase Parent; typedef typename Parent::Key Key; typedef typename Parent::Value Value; ConstMap() { } V operator[](const K&) const { return v; } void set(const K&, const V&) { } }; ///Returns a \ref ConstMap class ///This function just returns a \ref ConstMap class. ///\relates ConstMap template inline ConstMap, True> constMap() { return ConstMap, True>(); } /// \c std::map wrapper /// This is essentially a wrapper for \c std::map. With addition that /// you can specify a default value different from \c Value() . /// /// \todo Provide allocator parameter... template > class StdMap : public std::map { typedef std::map parent; T v; typedef typename parent::value_type PairType; public: ///\e typedef K Key; ///\e typedef T Value; ///\e typedef T& Reference; ///\e typedef const T& ConstReference; StdMap() : v() {} /// Constructor with specified default value StdMap(const T& _v) : v(_v) {} /// \brief Constructs the map from an appropriate std::map. /// /// \warning Inefficient: copies the content of \c m ! StdMap(const parent &m) : parent(m) {} /// \brief Constructs the map from an appropriate std::map, and explicitly /// specifies a default value. /// /// \warning Inefficient: copies the content of \c m ! StdMap(const parent &m, const T& _v) : parent(m), v(_v) {} template StdMap(const StdMap &m, const T &_v) { //FIXME; } Reference operator[](const Key &k) { return insert(PairType(k,v)).first -> second; } ConstReference operator[](const Key &k) const { typename parent::iterator i = lower_bound(k); if (i == parent::end() || parent::key_comp()(k, (*i).first)) return v; return (*i).second; } void set(const Key &k, const T &t) { parent::operator[](k) = t; } /// Changes the default value of the map. /// \return Returns the previous default value. /// /// \warning The value of some keys (which has already been queried, but /// the value has been unchanged from the default) may change! T setDefault(const T &_v) { T old=v; v=_v; return old; } template struct rebind { typedef StdMap other; }; }; /// @} /// \addtogroup map_adaptors /// @{ /// \brief Identity mapping. /// /// This mapping gives back the given key as value without any /// modification. template class IdentityMap : public MapBase { public: typedef MapBase Parent; typedef typename Parent::Key Key; typedef typename Parent::Value Value; const T& operator[](const T& t) const { return t; } }; ///Returns an \ref IdentityMap class ///This function just returns an \ref IdentityMap class. ///\relates IdentityMap template inline IdentityMap identityMap() { return IdentityMap(); } ///Convert the \c Value of a map to another type. ///This \ref concept::ReadMap "read only map" ///converts the \c Value of a maps to type \c T. ///Its \c Key is inherited from \c M. template class ConvertMap : public MapBase { typename SmartConstReference::Type m; public: typedef MapBase Parent; typedef typename Parent::Key Key; typedef typename Parent::Value Value; ///Constructor ///Constructor ///\param _m is the underlying map ConvertMap(const M &_m) : m(_m) {}; /// \brief The subscript operator. /// /// The subscript operator. /// \param k The key /// \return The target of the edge Value operator[](const Key& k) const {return m[k];} }; ///Returns an \ref ConvertMap class ///This function just returns an \ref ConvertMap class. ///\relates ConvertMap ///\todo The order of the template parameters are changed. template inline ConvertMap convertMap(const M &m) { return ConvertMap(m); } ///Sum of two maps ///This \ref concept::ReadMap "read only map" returns the sum of the two ///given maps. Its \c Key and \c Value will be inherited from \c M1. ///The \c Key and \c Value of M2 must be convertible to those of \c M1. template class AddMap : public MapBase { typename SmartConstReference::Type m1; typename SmartConstReference::Type m2; public: typedef MapBase Parent; typedef typename Parent::Key Key; typedef typename Parent::Value Value; ///Constructor AddMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {}; Value operator[](Key k) const {return m1[k]+m2[k];} }; ///Returns an \ref AddMap class ///This function just returns an \ref AddMap class. ///\todo How to call these type of functions? /// ///\relates AddMap ///\todo Wrong scope in Doxygen when \c \\relates is used template inline AddMap addMap(const M1 &m1,const M2 &m2) { return AddMap(m1,m2); } ///Shift a map with a constant. ///This \ref concept::ReadMap "read only map" returns the sum of the ///given map and a constant value. ///Its \c Key and \c Value is inherited from \c M. /// ///Actually, ///\code /// ShiftMap sh(x,v); ///\endcode ///is equivalent with ///\code /// ConstMap c_tmp(v); /// AddMap > sh(x,v); ///\endcode template class ShiftMap : public MapBase { typename SmartConstReference::Type m; typename M::Value v; public: typedef MapBase Parent; typedef typename Parent::Key Key; typedef typename Parent::Value Value; ///Constructor ///Constructor ///\param _m is the undelying map ///\param _v is the shift value ShiftMap(const M &_m, const Value &_v ) : m(_m), v(_v) {}; Value operator[](Key k) const {return m[k]+v;} }; ///Returns an \ref ShiftMap class ///This function just returns an \ref ShiftMap class. ///\relates ShiftMap ///\todo A better name is required. template inline ShiftMap shiftMap(const M &m,const typename M::Value &v) { return ShiftMap(m,v); } ///Difference of two maps ///This \ref concept::ReadMap "read only map" returns the difference ///of the values of the two ///given maps. Its \c Key and \c Value will be inherited from \c M1. ///The \c Key and \c Value of \c M2 must be convertible to those of \c M1. template class SubMap : public MapBase { typename SmartConstReference::Type m1; typename SmartConstReference::Type m2; public: typedef MapBase Parent; typedef typename Parent::Key Key; typedef typename Parent::Value Value; ///Constructor SubMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {}; Value operator[](Key k) const {return m1[k]-m2[k];} }; ///Returns a \ref SubMap class ///This function just returns a \ref SubMap class. /// ///\relates SubMap template inline SubMap subMap(const M1 &m1, const M2 &m2) { return SubMap(m1, m2); } ///Product of two maps ///This \ref concept::ReadMap "read only map" returns the product of the ///values of the two ///given ///maps. Its \c Key and \c Value will be inherited from \c M1. ///The \c Key and \c Value of \c M2 must be convertible to those of \c M1. template class MulMap : public MapBase { typename SmartConstReference::Type m1; typename SmartConstReference::Type m2; public: typedef MapBase Parent; typedef typename Parent::Key Key; typedef typename Parent::Value Value; ///Constructor MulMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {}; Value operator[](Key k) const {return m1[k]*m2[k];} }; ///Returns a \ref MulMap class ///This function just returns a \ref MulMap class. ///\relates MulMap template inline MulMap mulMap(const M1 &m1,const M2 &m2) { return MulMap(m1,m2); } ///Scales a maps with a constant. ///This \ref concept::ReadMap "read only map" returns the value of the ///given map multiplied with a constant value. ///Its \c Key and \c Value is inherited from \c M. /// ///Actually, ///\code /// ScaleMap sc(x,v); ///\endcode ///is equivalent with ///\code /// ConstMap c_tmp(v); /// MulMap > sc(x,v); ///\endcode template class ScaleMap : public MapBase { typename SmartConstReference::Type m; typename M::Value v; public: typedef MapBase Parent; typedef typename Parent::Key Key; typedef typename Parent::Value Value; ///Constructor ///Constructor ///\param _m is the undelying map ///\param _v is the scaling value ScaleMap(const M &_m,const Value &_v ) : m(_m), v(_v) {}; Value operator[](Key k) const {return m[k]*v;} }; ///Returns an \ref ScaleMap class ///This function just returns an \ref ScaleMap class. ///\relates ScaleMap ///\todo A better name is required. template inline ScaleMap scaleMap(const M &m,const typename M::Value &v) { return ScaleMap(m,v); } ///Quotient of two maps ///This \ref concept::ReadMap "read only map" returns the quotient of the ///values of the two ///given maps. Its \c Key and \c Value will be inherited from \c M1. ///The \c Key and \c Value of \c M2 must be convertible to those of \c M1. template class DivMap : public MapBase { typename SmartConstReference::Type m1; typename SmartConstReference::Type m2; public: typedef MapBase Parent; typedef typename Parent::Key Key; typedef typename Parent::Value Value; ///Constructor DivMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {}; Value operator[](Key k) const {return m1[k]/m2[k];} }; ///Returns a \ref DivMap class ///This function just returns a \ref DivMap class. ///\relates DivMap template inline DivMap divMap(const M1 &m1,const M2 &m2) { return DivMap(m1,m2); } ///Composition of two maps ///This \ref concept::ReadMap "read only map" returns the composition of ///two ///given maps. That is to say, if \c m1 is of type \c M1 and \c m2 is ///of \c M2, ///then for ///\code /// ComposeMap cm(m1,m2); ///\endcode /// cm[x] will be equal to m1[m2[x]] /// ///Its \c Key is inherited from \c M2 and its \c Value is from ///\c M1. ///The \c M2::Value must be convertible to \c M1::Key. ///\todo Check the requirements. template class ComposeMap : public MapBase { typename SmartConstReference::Type m1; typename SmartConstReference::Type m2; public: typedef MapBase Parent; typedef typename Parent::Key Key; typedef typename Parent::Value Value; ///Constructor ComposeMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {}; Value operator[](Key k) const {return m1[m2[k]];} }; ///Returns a \ref ComposeMap class ///This function just returns a \ref ComposeMap class. /// ///\relates ComposeMap template inline ComposeMap composeMap(const M1 &m1,const M2 &m2) { return ComposeMap(m1,m2); } ///Combines of two maps using an STL (binary) functor. ///Combines of two maps using an STL (binary) functor. /// /// ///This \ref concept::ReadMap "read only map" takes two maps and a ///binary functor and returns the composition of ///the two ///given maps unsing the functor. ///That is to say, if \c m1 and \c m2 is of type \c M1 and \c M2 ///and \c f is of \c F, ///then for ///\code /// CombineMap cm(m1,m2,f); ///\endcode /// cm[x] will be equal to f(m1[x],m2[x]) /// ///Its \c Key is inherited from \c M1 and its \c Value is \c V. ///The \c M2::Value and \c M1::Value must be convertible to the corresponding ///input parameter of \c F and the return type of \c F must be convertible ///to \c V. ///\todo Check the requirements. template class CombineMap : public MapBase { typename SmartConstReference::Type m1; typename SmartConstReference::Type m2; F f; public: typedef MapBase Parent; typedef typename Parent::Key Key; typedef typename Parent::Value Value; ///Constructor CombineMap(const M1 &_m1,const M2 &_m2,const F &_f) : m1(_m1), m2(_m2), f(_f) {}; Value operator[](Key k) const {return f(m1[k],m2[k]);} }; ///Returns a \ref CombineMap class ///This function just returns a \ref CombineMap class. /// ///Only the first template parameter (the value type) must be given. /// ///For example if \c m1 and \c m2 are both \c double valued maps, then ///\code ///combineMap(m1,m2,std::plus) ///\endcode ///is equivalent with ///\code ///addMap(m1,m2) ///\endcode /// ///\relates CombineMap template inline CombineMap combineMap(const M1& m1,const M2& m2, const F& f) { return CombineMap(m1,m2,f); } template inline CombineMap combineMap(const M1& m1, const M2& m2, const F& f) { return combineMap(m1,m2,f); } template inline CombineMap combineMap(const M1 &m1, const M2 &m2, V (*f)(K1, K2)) { return combineMap(m1,m2,f); } ///Negative value of a map ///This \ref concept::ReadMap "read only map" returns the negative ///value of the ///value returned by the ///given map. Its \c Key and \c Value will be inherited from \c M. ///The unary \c - operator must be defined for \c Value, of course. template class NegMap : public MapBase { typename SmartConstReference::Type m; public: typedef MapBase Parent; typedef typename Parent::Key Key; typedef typename Parent::Value Value; ///Constructor NegMap(const M &_m) : m(_m) {}; Value operator[](Key k) const {return -m[k];} }; ///Returns a \ref NegMap class ///This function just returns a \ref NegMap class. ///\relates NegMap template inline NegMap negMap(const M &m) { return NegMap(m); } ///Absolute value of a map ///This \ref concept::ReadMap "read only map" returns the absolute value ///of the ///value returned by the ///given map. Its \c Key and \c Value will be inherited ///from M. Value ///must be comparable to 0 and the unary - ///operator must be defined for it, of course. /// ///\bug We need a unified way to handle the situation below: ///\code /// struct _UnConvertible {}; /// template inline A t_abs(A a) {return _UnConvertible();} /// template<> inline int t_abs<>(int n) {return abs(n);} /// template<> inline long int t_abs<>(long int n) {return labs(n);} /// template<> inline long long int t_abs<>(long long int n) {return ::llabs(n);} /// template<> inline float t_abs<>(float n) {return fabsf(n);} /// template<> inline double t_abs<>(double n) {return fabs(n);} /// template<> inline long double t_abs<>(long double n) {return fabsl(n);} ///\endcode template class AbsMap : public MapBase { typename SmartConstReference::Type m; public: typedef MapBase Parent; typedef typename Parent::Key Key; typedef typename Parent::Value Value; ///Constructor AbsMap(const M &_m) : m(_m) {}; Value operator[](Key k) const { Value tmp = m[k]; return tmp >= 0 ? tmp : -tmp; } }; ///Returns a \ref AbsMap class ///This function just returns a \ref AbsMap class. ///\relates AbsMap template inline AbsMap absMap(const M &m) { return AbsMap(m); } ///Converts an STL style functor to a map ///This \ref concept::ReadMap "read only map" returns the value ///of a ///given map. /// ///Template parameters \c K and \c V will become its ///\c Key and \c Value. They must be given explicitely ///because a functor does not provide such typedefs. /// ///Parameter \c F is the type of the used functor. template class FunctorMap : public MapBase { const F &f; public: typedef MapBase Parent; typedef typename Parent::Key Key; typedef typename Parent::Value Value; ///Constructor FunctorMap(const F &_f) : f(_f) {}; Value operator[](Key k) const {return f(k);} }; ///Returns a \ref FunctorMap class ///This function just returns a \ref FunctorMap class. /// ///The third template parameter isn't necessary to be given. ///\relates FunctorMap template inline FunctorMap functorMap(const F &f) { return FunctorMap(f); } template inline FunctorMap functorMap(const F &f) { return functorMap(f); } template inline FunctorMap functorMap(V (*f)(K)) { return functorMap(f); } ///Converts a map to an STL style (unary) functor ///This class Converts a map to an STL style (unary) functor. ///that is it provides an operator() to read its values. /// ///For the sake of convenience it also works as ///a ususal \ref concept::ReadMap "readable map", ///i.e. operator[] and the \c Key and \c Value typedefs also exist. template class MapFunctor : public MapBase { typename SmartConstReference::Type m; public: typedef MapBase Parent; typedef typename Parent::Key Key; typedef typename Parent::Value Value; ///\e typedef typename M::Key argument_type; ///\e typedef typename M::Value result_type; ///Constructor MapFunctor(const M &_m) : m(_m) {}; ///Returns a value of the map Value operator()(Key k) const {return m[k];} ///\e Value operator[](Key k) const {return m[k];} }; ///Returns a \ref MapFunctor class ///This function just returns a \ref MapFunctor class. ///\relates MapFunctor template inline MapFunctor mapFunctor(const M &m) { return MapFunctor(m); } ///Applies all map setting operations to two maps ///This map has two \ref concept::WriteMap "writable map" ///parameters and each write request will be passed to both of them. ///If \c M1 is also \ref concept::ReadMap "readable", ///then the read operations will return the ///corresponding values of \c M1. /// ///The \c Key and \c Value will be inherited from \c M1. ///The \c Key and \c Value of M2 must be convertible from those of \c M1. template class ForkMap : public MapBase { typename SmartConstReference::Type m1; typename SmartConstReference::Type m2; public: typedef MapBase Parent; typedef typename Parent::Key Key; typedef typename Parent::Value Value; ///Constructor ForkMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {}; Value operator[](Key k) const {return m1[k];} // void set(Key k, const Value &v) {m1.set(k,v); m2.set(k,v);} }; ///Returns an \ref ForkMap class ///This function just returns an \ref ForkMap class. ///\todo How to call these type of functions? /// ///\relates ForkMap ///\todo Wrong scope in Doxygen when \c \\relates is used template inline ForkMap forkMap(const M1 &m1,const M2 &m2) { return ForkMap(m1,m2); } /* ************* BOOL MAPS ******************* */ ///Logical 'not' of a map ///This bool \ref concept::ReadMap "read only map" returns the ///logical negation of ///value returned by the ///given map. Its \c Key and will be inherited from \c M, ///its Value is bool. template class NotMap : public MapBase { typename SmartConstReference::Type m; public: typedef MapBase Parent; typedef typename Parent::Key Key; typedef typename Parent::Value Value; ///Constructor NotMap(const M &_m) : m(_m) {}; Value operator[](Key k) const {return !m[k];} }; ///Returns a \ref NotMap class ///This function just returns a \ref NotMap class. ///\relates NotMap template inline NotMap notMap(const M &m) { return NotMap(m); } /// @} } #endif // LEMON_MAPS_H