1.1 --- a/src/lemon/maps.h Thu Dec 16 12:44:49 2004 +0000
1.2 +++ b/src/lemon/maps.h Mon Jan 03 16:19:46 2005 +0000
1.3 @@ -17,7 +17,10 @@
1.4 #ifndef LEMON_MAPS_H
1.5 #define LEMON_MAPS_H
1.6
1.7 +#include<math.h>
1.8 +
1.9 ///\file
1.10 +///\ingroup maps
1.11 ///\brief Miscellaneous property maps
1.12 ///
1.13 ///\todo This file has the same name as the concept file in concept/,
1.14 @@ -27,6 +30,9 @@
1.15
1.16 namespace lemon {
1.17
1.18 + /// \addtogroup maps
1.19 + /// @{
1.20 +
1.21 /// Base class of maps.
1.22
1.23 /// Base class of maps.
1.24 @@ -168,6 +174,277 @@
1.25 typedef StdMap<Key,T1,Compare> other;
1.26 };
1.27 };
1.28 +
1.29 +
1.30 + ///Sum of two maps
1.31 +
1.32 + ///This \ref concept::ReadMap "read only map" returns the sum of the two
1.33 + ///given maps. Its \c Key and \c Value will be inherited from \c M1.
1.34 + ///The \c Key and \c Value of M2 must be convertible to those of \c M1.
1.35 +
1.36 + template<class M1,class M2>
1.37 + class AddMap
1.38 + {
1.39 + const M1 &m1;
1.40 + const M2 &m2;
1.41 + public:
1.42 + typedef typename M1::Key Key;
1.43 + typedef typename M1::Value Value;
1.44 +
1.45 + ///Constructor
1.46 +
1.47 + ///\e
1.48 + ///
1.49 + AddMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
1.50 + Value operator[](Key k) {return m1[k]+m2[k];}
1.51 + };
1.52 +
1.53 + ///Returns an \ref AddMap class
1.54 +
1.55 + ///This function just returns an \ref AddMap class.
1.56 + ///\todo How to call these type of functions?
1.57 + ///
1.58 + ///\relates AddMap
1.59 + ///\todo Wrong scope in Doxygen when \c \\relates is used
1.60 + template<class M1,class M2>
1.61 + inline AddMap<M1,M2> addMap(const M1 &m1,const M2 &m2)
1.62 + {
1.63 + return AddMap<M1,M2>(m1,m2);
1.64 + }
1.65 +
1.66 + ///Difference of two maps
1.67 +
1.68 + ///This \ref concept::ReadMap "read only map" returns the difference
1.69 + ///of the values returned by the two
1.70 + ///given maps. Its \c Key and \c Value will be inherited from \c M1.
1.71 + ///The \c Key and \c Value of \c M2 must be convertible to those of \c M1.
1.72 +
1.73 + template<class M1,class M2>
1.74 + class SubMap
1.75 + {
1.76 + const M1 &m1;
1.77 + const M2 &m2;
1.78 + public:
1.79 + typedef typename M1::Key Key;
1.80 + typedef typename M1::Value Value;
1.81 +
1.82 + ///Constructor
1.83 +
1.84 + ///\e
1.85 + ///
1.86 + SubMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
1.87 + Value operator[](Key k) {return m1[k]-m2[k];}
1.88 + };
1.89 +
1.90 + ///Returns a \ref SubMap class
1.91 +
1.92 + ///This function just returns a \ref SubMap class.
1.93 + ///
1.94 + ///\relates SubMap
1.95 + template<class M1,class M2>
1.96 + inline SubMap<M1,M2> subMap(const M1 &m1,const M2 &m2)
1.97 + {
1.98 + return SubMap<M1,M2>(m1,m2);
1.99 + }
1.100 +
1.101 + ///Product of two maps
1.102 +
1.103 + ///This \ref concept::ReadMap "read only map" returns the product of the
1.104 + ///values returned by the two
1.105 + ///given
1.106 + ///maps. Its \c Key and \c Value will be inherited from \c M1.
1.107 + ///The \c Key and \c Value of \c M2 must be convertible to those of \c M1.
1.108 +
1.109 + template<class M1,class M2>
1.110 + class MulMap
1.111 + {
1.112 + const M1 &m1;
1.113 + const M2 &m2;
1.114 + public:
1.115 + typedef typename M1::Key Key;
1.116 + typedef typename M1::Value Value;
1.117 +
1.118 + ///Constructor
1.119 +
1.120 + ///\e
1.121 + ///
1.122 + MulMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
1.123 + Value operator[](Key k) {return m1[k]*m2[k];}
1.124 + };
1.125 +
1.126 + ///Returns a \ref MulMap class
1.127 +
1.128 + ///This function just returns a \ref MulMap class.
1.129 + ///\relates MulMap
1.130 + template<class M1,class M2>
1.131 + inline MulMap<M1,M2> mulMap(const M1 &m1,const M2 &m2)
1.132 + {
1.133 + return MulMap<M1,M2>(m1,m2);
1.134 + }
1.135 +
1.136 + ///Quotient of two maps
1.137 +
1.138 + ///This \ref concept::ReadMap "read only map" returns the quotient of the
1.139 + ///values returned by the two
1.140 + ///given maps. Its \c Key and \c Value will be inherited from \c M1.
1.141 + ///The \c Key and \c Value of \c M2 must be convertible to those of \c M1.
1.142 +
1.143 + template<class M1,class M2>
1.144 + class DivMap
1.145 + {
1.146 + const M1 &m1;
1.147 + const M2 &m2;
1.148 + public:
1.149 + typedef typename M1::Key Key;
1.150 + typedef typename M1::Value Value;
1.151 +
1.152 + ///Constructor
1.153 +
1.154 + ///\e
1.155 + ///
1.156 + DivMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
1.157 + Value operator[](Key k) {return m1[k]/m2[k];}
1.158 + };
1.159 +
1.160 + ///Returns a \ref DivMap class
1.161 +
1.162 + ///This function just returns a \ref DivMap class.
1.163 + ///\relates DivMap
1.164 + template<class M1,class M2>
1.165 + inline DivMap<M1,M2> divMap(const M1 &m1,const M2 &m2)
1.166 + {
1.167 + return DivMap<M1,M2>(m1,m2);
1.168 + }
1.169 +
1.170 + ///Composition of two maps
1.171 +
1.172 + ///This \ref concept::ReadMap "read only map" returns the composition of
1.173 + ///two
1.174 + ///given maps. That is to say, if \c m1 is of type \c M1 and \c m2 is
1.175 + ///of \c M2,
1.176 + ///then for
1.177 + ///\code
1.178 + /// ComposeMap<M1,M2> cm(m1,m2);
1.179 + ///\endcode
1.180 + ///<tt>cm[x]</tt> will be equal to <tt>m1[m2[x]]</tt>
1.181 + ///
1.182 + ///Its \c Key is inherited from \c M2 and its \c Value is from
1.183 + ///\c M1.
1.184 + ///The \c M2::Value must be convertible to \c M1::Key.
1.185 + ///\todo Check the requirements.
1.186 +
1.187 + template<class M1,class M2>
1.188 + class ComposeMap
1.189 + {
1.190 + const M1 &m1;
1.191 + const M2 &m2;
1.192 + public:
1.193 + typedef typename M2::Key Key;
1.194 + typedef typename M1::Value Value;
1.195 +
1.196 + ///Constructor
1.197 +
1.198 + ///\e
1.199 + ///
1.200 + ComposeMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
1.201 + Value operator[](Key k) {return m1[m2[k]];}
1.202 + };
1.203 +
1.204 + ///Returns a \ref ComposeMap class
1.205 +
1.206 + ///This function just returns a \ref ComposeMap class.
1.207 + ///\relates ComposeMap
1.208 + template<class M1,class M2>
1.209 + inline ComposeMap<M1,M2> composeMap(const M1 &m1,const M2 &m2)
1.210 + {
1.211 + return ComposeMap<M1,M2>(m1,m2);
1.212 + }
1.213 +
1.214 + ///Negative value of a map
1.215 +
1.216 + ///This \ref concept::ReadMap "read only map" returns the negative
1.217 + ///value of the
1.218 + ///value returned by the
1.219 + ///given map. Its \c Key and \c Value will be inherited from \c M.
1.220 + ///The unary \c - operator must be defined for \c Value, of course.
1.221 +
1.222 + template<class M>
1.223 + class NegMap
1.224 + {
1.225 + const M &m;
1.226 + public:
1.227 + typedef typename M::Key Key;
1.228 + typedef typename M::Value Value;
1.229 +
1.230 + ///Constructor
1.231 +
1.232 + ///\e
1.233 + ///
1.234 + NegMap(const M &_m) : m(_m) {};
1.235 + Value operator[](Key k) {return -m[k];}
1.236 + };
1.237 +
1.238 + ///Returns a \ref NegMap class
1.239 +
1.240 + ///This function just returns a \ref NegMap class.
1.241 + ///\relates NegMap
1.242 + template<class M>
1.243 + inline NegMap<M> negMap(const M &m)
1.244 + {
1.245 + return NegMap<M>(m);
1.246 + }
1.247 +
1.248 +
1.249 + //\todo We need a unified way to handle the situation below!
1.250 + struct _UnConvertible {};
1.251 + template<class A> inline A t_abs(A a) {return _UnConvertible();}
1.252 +
1.253 + template<> inline int t_abs<>(int n) {return abs(n);}
1.254 + template<> inline long int t_abs<>(long int n) {return labs(n);}
1.255 + //\bug llabs() is overloaded
1.256 + template<> inline long long int t_abs<>(long long int n) {return ::llabs(n);}
1.257 +
1.258 + template<> inline float t_abs<>(float n) {return fabsf(n);}
1.259 + template<> inline double t_abs<>(double n) {return fabs(n);}
1.260 + template<> inline long double t_abs<>(long double n) {return fabsl(n);}
1.261 +
1.262 + ///Absolute value of a map
1.263 +
1.264 + ///This \ref concept::ReadMap "read only map" returns the absolute value
1.265 + ///of the
1.266 + ///value returned by the
1.267 + ///given map. Its \c Key and \c Value will be inherited from \c M.
1.268 + ///The function <tt>Value abs(Value)<tt> must be defined, of course.
1.269 +
1.270 + template<class M>
1.271 + class AbsMap
1.272 + {
1.273 + const M &m;
1.274 + public:
1.275 + typedef typename M::Key Key;
1.276 + typedef typename M::Value Value;
1.277 +
1.278 + ///Constructor
1.279 +
1.280 + ///\e
1.281 + ///
1.282 + AbsMap(const M &_m) : m(_m) {};
1.283 + Value operator[](Key k) {return t_abs(m[k]);}
1.284 + };
1.285 +
1.286 + ///Returns a \ref AbsMap class
1.287 +
1.288 + ///This function just returns a \ref AbsMap class.
1.289 + ///\relates AbsMap
1.290 + template<class M>
1.291 + inline AbsMap<M> absMap(const M &m)
1.292 + {
1.293 + return AbsMap<M>(m);
1.294 + }
1.295 +
1.296 + /// @}
1.297
1.298 }
1.299 +
1.300 +
1.301 #endif // LEMON_MAPS_H
2.1 --- a/src/test/Makefile.am Thu Dec 16 12:44:49 2004 +0000
2.2 +++ b/src/test/Makefile.am Mon Jan 03 16:19:46 2005 +0000
2.3 @@ -17,6 +17,7 @@
2.4 graph_wrapper_test \
2.5 graph_utils_test \
2.6 kruskal_test \
2.7 + maps_test \
2.8 min_cost_flow_test \
2.9 suurballe_test \
2.10 path_test \
2.11 @@ -38,6 +39,7 @@
2.12 graph_utils_test_SOURCES = graph_utils_test.cc
2.13 graph_wrapper_test_SOURCES = graph_wrapper_test.cc
2.14 kruskal_test_SOURCES = kruskal_test.cc
2.15 +maps_test_SOURCES = maps_test.cc
2.16 min_cost_flow_test_SOURCES = min_cost_flow_test.cc
2.17 suurballe_test_SOURCES = suurballe_test.cc
2.18 path_test_SOURCES = path_test.cc
3.1 --- a/src/test/map_test.h Thu Dec 16 12:44:49 2004 +0000
3.2 +++ b/src/test/map_test.h Mon Jan 03 16:19:46 2005 +0000
3.3 @@ -24,7 +24,7 @@
3.4
3.5 //! \ingroup misc
3.6 //! \file
3.7 -//! \brief Some utility to test map classes.
3.8 +//! \brief Some utilities to test map classes.
3.9
3.10 namespace lemon {
3.11
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/src/test/maps_test.cc Mon Jan 03 16:19:46 2005 +0000
4.3 @@ -0,0 +1,35 @@
4.4 +#include <lemon/concept_check.h>
4.5 +#include <lemon/concept/maps.h>
4.6 +#include <lemon/maps.h>
4.7 +
4.8 +#include "test_tools.h"
4.9 +
4.10 +using namespace lemon;
4.11 +using namespace lemon::concept;
4.12 +
4.13 +struct A {};
4.14 +struct B {};
4.15 +
4.16 +typedef ReadMap<A,double> DoubleMap;
4.17 +
4.18 +int main()
4.19 +{ // checking graph components
4.20 +
4.21 + checkConcept<ReadMap<A,B>, ReadMap<A,B> >();
4.22 + checkConcept<WriteMap<A,B>, WriteMap<A,B> >();
4.23 + checkConcept<ReadWriteMap<A,B>, ReadWriteMap<A,B> >();
4.24 + checkConcept<ReferenceMap<A,B,B&,const B&>, ReferenceMap<A,B,B&,const B&> >();
4.25 +
4.26 + checkConcept<ReadMap<A,double>, AddMap<DoubleMap,DoubleMap> >();
4.27 + checkConcept<ReadMap<A,double>, SubMap<DoubleMap,DoubleMap> >();
4.28 + checkConcept<ReadMap<A,double>, MulMap<DoubleMap,DoubleMap> >();
4.29 + checkConcept<ReadMap<A,double>, DivMap<DoubleMap,DoubleMap> >();
4.30 + checkConcept<ReadMap<A,double>, NegMap<DoubleMap> >();
4.31 + checkConcept<ReadMap<A,double>, AbsMap<DoubleMap> >();
4.32 +
4.33 + checkConcept<ReadMap<B,double>, ComposeMap<DoubleMap,ReadMap<B,A> > >();
4.34 +
4.35 + std::cout << __FILE__ ": All tests passed.\n";
4.36 +
4.37 + return 0;
4.38 +}