diff -r d8475431bbbb -r 8e85e6bbefdf lemon/maps.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lemon/maps.h Mon May 23 04:48:14 2005 +0000 @@ -0,0 +1,841 @@ +/* -*- 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 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 True NeedCopy; + + /// 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 + { + T v; + public: + + typedef True NeedCopy; + + /// 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 K &k) + { + return ConstMap(k); + } + + + //to document later + template + struct Const { }; + //to document later + template + class ConstMap > : public MapBase + { + public: + ConstMap() { } + V operator[](const K&) const { return v; } + void set(const K&, const V&) { } + }; + + /// \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: + typedef K Key; + typedef T Value; + typedef T& Reference; + 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 + /// @{ + + + ///Convert the \c Value of a maps to another type. + + ///This \ref concept::ReadMap "read only map" + ///converts the \c Value of a maps to type \c T. + ///Its \c Value is inherited from \c M. + /// + ///Actually, + ///\code + /// ConvertMap sh(x,v); + ///\endcode + ///it is equivalent with + ///\code + /// ConstMap c_tmp(v); + /// AddMap > sh(x,v); + ///\endcode + ///\bug wrong documentation + template + class ConvertMap { + typename SmartConstReference::Type m; + public: + + typedef True NeedCopy; + + typedef typename M::Key Key; + typedef T Value; + + ///Constructor + + ///Constructor + ///\param _m is the undelying map + ///\param _v is the convert value + ConvertMap(const M &_m) : m(_m) {}; + + /// \brief The subscript operator. + /// + /// The subscript operator. + /// \param edge The edge + /// \return The target of the edge + Value operator[](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 + { + typename SmartConstReference::Type m1; + typename SmartConstReference::Type m2; + + public: + + typedef True NeedCopy; + + typedef typename M1::Key Key; + typedef typename M1::Value Value; + + ///Constructor + + ///\e + /// + 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 maps 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 + ///it is equivalent with + ///\code + /// ConstMap c_tmp(v); + /// AddMap > sh(x,v); + ///\endcode + template + class ShiftMap + { + typename SmartConstReference::Type m; + typename M::Value v; + public: + + typedef True NeedCopy; + typedef typename M::Key Key; + typedef typename M::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 returned by 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 + { + typename SmartConstReference::Type m1; + typename SmartConstReference::Type m2; + public: + + typedef True NeedCopy; + typedef typename M1::Key Key; + typedef typename M1::Value Value; + + ///Constructor + + ///\e + /// + 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 returned by 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 + { + typename SmartConstReference::Type m1; + typename SmartConstReference::Type m2; + public: + + typedef True NeedCopy; + typedef typename M1::Key Key; + typedef typename M1::Value Value; + + ///Constructor + + ///\e + /// + 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); + } + + ///Scale a maps with a constant. + + ///This \ref concept::ReadMap "read only map" returns the value of the + ///given map multipied with a constant value. + ///Its \c Key and \c Value is inherited from \c M. + /// + ///Actually, + ///\code + /// ScaleMap sc(x,v); + ///\endcode + ///it is equivalent with + ///\code + /// ConstMap c_tmp(v); + /// MulMap > sc(x,v); + ///\endcode + template + class ScaleMap + { + typename SmartConstReference::Type m; + typename M::Value v; + public: + + typedef True NeedCopy; + typedef typename M::Key Key; + typedef typename M::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 returned by 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 + { + typename SmartConstReference::Type m1; + typename SmartConstReference::Type m2; + public: + + typedef True NeedCopy; + typedef typename M1::Key Key; + typedef typename M1::Value Value; + + ///Constructor + + ///\e + /// + 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 + { + typename SmartConstReference::Type m1; + typename SmartConstReference::Type m2; + public: + + typedef True NeedCopy; + typedef typename M2::Key Key; + typedef typename M1::Value Value; + + typedef True NeedCopy; + + ///Constructor + + ///\e + /// + 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); + } + + ///Combine of two maps using an STL (binary) functor. + + ///Combine of two maps using an STL (binary) functor. + /// + /// + ///This \ref concept::ReadMap "read only map" takes to maps and a + ///binary functor and returns the composition of + ///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 + { + typename SmartConstReference::Type m1; + typename SmartConstReference::Type m2; + F f; + public: + + typedef True NeedCopy; + typedef typename M1::Key Key; + typedef V Value; + + ///Constructor + + ///\e + /// + 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); + } + + ///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 + { + typename SmartConstReference::Type m; + public: + + typedef True NeedCopy; + typedef typename M::Key Key; + typedef typename M::Value Value; + + ///Constructor + + ///\e + /// + 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 + { + typename SmartConstReference::Type m; + public: + + typedef True NeedCopy; + typedef typename M::Key Key; + typedef typename M::Value Value; + + ///Constructor + + ///\e + /// + 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 + { + const F &f; + public: + + typedef True NeedCopy; + typedef K Key; + typedef V Value; + + ///Constructor + + ///\e + /// + 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); + } + + ///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 + { + typename SmartConstReference::Type m; + public: + + typedef True NeedCopy; + typedef typename M::Key argument_type; + typedef typename M::Value result_type; + typedef typename M::Key Key; + typedef typename M::Value Value; + + ///Constructor + + ///\e + /// + MapFunctor(const M &_m) : m(_m) {}; + ///Returns a value of the map + + ///\e + /// + 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); + } + + + ///Apply 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 + { + typename SmartConstReference::Type m1; + typename SmartConstReference::Type m2; + public: + + typedef True NeedCopy; + typedef typename M1::Key Key; + typedef typename M1::Value Value; + + ///Constructor + + ///\e + /// + 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); + } + + /// @} + +} + + +#endif // LEMON_MAPS_H