diff --git a/lemon/concept_check.h b/lemon/concept_check.h new file mode 100644 --- /dev/null +++ b/lemon/concept_check.h @@ -0,0 +1,105 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2007 + * 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. + * + */ + +// This file contains a modified version of the concept checking +// utility from BOOST. +// See the appropriate copyright notice below. + +// (C) Copyright Jeremy Siek 2000. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Revision History: +// 05 May 2001: Workarounds for HP aCC from Thomas Matelich. (Jeremy Siek) +// 02 April 2001: Removed limits header altogether. (Jeremy Siek) +// 01 April 2001: Modified to use new header. (JMaddock) +// + +// See http://www.boost.org/libs/concept_check for documentation. + +#ifndef LEMON_CONCEPT_CHECKS_H +#define LEMON_CONCEPT_CHECKS_H + +namespace lemon { + + /* + "inline" is used for ignore_unused_variable_warning() + and function_requires() to make sure there is no + overtarget with g++. + */ + + template inline void ignore_unused_variable_warning(const T&) { } + + template + inline void function_requires() + { +#if !defined(NDEBUG) + void (Concept::*x)() = & Concept::constraints; + ignore_unused_variable_warning(x); +#endif + } + + template + inline void checkConcept() { +#if !defined(NDEBUG) + typedef typename Concept::template Constraints ConceptCheck; + void (ConceptCheck::*x)() = & ConceptCheck::constraints; + ignore_unused_variable_warning(x); +#endif + } + +#define BOOST_CLASS_REQUIRE(type_var, ns, concept) \ + typedef void (ns::concept ::* func##type_var##concept)(); \ + template \ + struct concept_checking_##type_var##concept { }; \ + typedef concept_checking_##type_var##concept< \ + BOOST_FPTR ns::concept::constraints> \ + concept_checking_typedef_##type_var##concept + +#define BOOST_CLASS_REQUIRE2(type_var1, type_var2, ns, concept) \ + typedef void (ns::concept ::* \ + func##type_var1##type_var2##concept)(); \ + template \ + struct concept_checking_##type_var1##type_var2##concept { }; \ + typedef concept_checking_##type_var1##type_var2##concept< \ + BOOST_FPTR ns::concept::constraints> \ + concept_checking_typedef_##type_var1##type_var2##concept + +#define BOOST_CLASS_REQUIRE3(tv1, tv2, tv3, ns, concept) \ + typedef void (ns::concept ::* \ + func##tv1##tv2##tv3##concept)(); \ + template \ + struct concept_checking_##tv1##tv2##tv3##concept { }; \ + typedef concept_checking_##tv1##tv2##tv3##concept< \ + BOOST_FPTR ns::concept::constraints> \ + concept_checking_typedef_##tv1##tv2##tv3##concept + +#define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \ + typedef void (ns::concept ::* \ + func##tv1##tv2##tv3##tv4##concept)(); \ + template \ + struct concept_checking_##tv1##tv2##tv3##tv4##concept { }; \ + typedef concept_checking_##tv1##tv2##tv3##tv4##concept< \ + BOOST_FPTR ns::concept::constraints> \ + concept_checking_typedef_##tv1##tv2##tv3##tv4##concept + + +} // namespace lemon + +#endif // LEMON_CONCEPT_CHECKS_H diff --git a/lemon/concepts/maps.h b/lemon/concepts/maps.h new file mode 100644 --- /dev/null +++ b/lemon/concepts/maps.h @@ -0,0 +1,207 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2007 + * 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_CONCEPT_MAPS_H +#define LEMON_CONCEPT_MAPS_H + +#include +#include + +///\ingroup concept +///\file +///\brief Map concepts checking classes for testing and documenting. + +namespace lemon { + + namespace concepts { + + /// \addtogroup concept + /// @{ + + /// Readable map concept + + /// Readable map concept. + /// + template + class ReadMap + { + public: + /// Map's key type. + typedef K Key; + /// Map's value type. (The type of objects associated with the keys). + typedef T Value; + + /// Returns the value associated with a key. + + /// \bug Value shouldn't need to be default constructible. + /// + Value operator[](const Key &) const {return Value();} + + template + struct Constraints { + + void constraints() { + Value val = m[key]; + val = m[key]; + typename _ReadMap::Value own_val = m[own_key]; + own_val = m[own_key]; + + ignore_unused_variable_warning(val); + ignore_unused_variable_warning(own_val); + ignore_unused_variable_warning(key); + } + Key& key; + typename _ReadMap::Key& own_key; + _ReadMap& m; + }; + + }; + + + /// Writable map concept + + /// Writable map concept. + /// + template + class WriteMap + { + public: + /// Map's key type. + typedef K Key; + /// Map's value type. (The type of objects associated with the keys). + typedef T Value; + + /// Sets the value associated with a key. + void set(const Key &,const Value &) {} + + ///Default constructor + WriteMap() {} + + template + struct Constraints { + void constraints() { + // No constraints for constructor. + m.set(key, val); + m.set(own_key, own_val); + ignore_unused_variable_warning(key); + ignore_unused_variable_warning(val); + ignore_unused_variable_warning(own_key); + ignore_unused_variable_warning(own_val); + } + + Value& val; + typename _WriteMap::Value own_val; + Key& key; + typename _WriteMap::Key& own_key; + _WriteMap& m; + + }; + }; + + /// Read/Writable map concept + + /// Read/writable map concept. + /// + template + class ReadWriteMap : public ReadMap, + public WriteMap + { + public: + /// Map's key type. + typedef K Key; + /// Map's value type. (The type of objects associated with the keys). + typedef T Value; + + /// Returns the value associated with a key. + Value operator[](const Key &) const {return Value();} + /// Sets the value associated with a key. + void set(const Key & ,const Value &) {} + + template + struct Constraints { + void constraints() { + checkConcept, _ReadWriteMap >(); + checkConcept, _ReadWriteMap >(); + } + }; + }; + + + /// Dereferable map concept + + /// Dereferable map concept. + /// + template + class ReferenceMap : public ReadWriteMap + { + public: + /// Tag for reference maps. + typedef True ReferenceMapTag; + /// Map's key type. + typedef K Key; + /// Map's value type. (The type of objects associated with the keys). + typedef T Value; + /// Map's reference type. + typedef R Reference; + /// Map's const reference type. + typedef CR ConstReference; + + protected: + Value tmp; + public: + + ///Returns a reference to the value associated to a key. + Reference operator[](const Key &) { return tmp; } + ///Returns a const reference to the value associated to a key. + ConstReference operator[](const Key &) const { return tmp; } + /// Sets the value associated with a key. + void set(const Key &k,const Value &t) { operator[](k)=t; } + + /// \todo Rethink this concept. + template + struct ReferenceMapConcept { + + void constraints() { + checkConcept(); + m[key] = val; + val = m[key]; + m[key] = ref; + ref = m[key]; + m[own_key] = own_val; + own_val = m[own_key]; + m[own_key] = own_ref; + own_ref = m[own_key]; + } + + typename _ReferenceMap::Key& own_key; + typename _ReferenceMap::Value& own_val; + typename _ReferenceMap::Reference& own_ref; + Key& key; + Value& val; + Reference& ref; + _ReferenceMap& m; + }; + }; + + // @} + + } //namespace concepts + +} //namespace lemon + +#endif // LEMON_CONCEPT_MAPS_H diff --git a/lemon/maps.h b/lemon/maps.h new file mode 100644 --- /dev/null +++ b/lemon/maps.h @@ -0,0 +1,1568 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2007 + * 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 +#include + +#include +// #include + +///\file +///\ingroup maps +///\brief Miscellaneous property maps +/// +#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) + + /// This map can be used 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 is not required (i.e. it will be 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&) {} + }; + + ///Returns a \c NullMap class + + ///This function just returns a \c NullMap class. + ///\relates NullMap + 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 \c NullMap. + template + class ConstMap : public MapBase { + private: + T v; + public: + + typedef MapBase Parent; + typedef typename Parent::Key Key; + typedef typename Parent::Value Value; + + /// Default constructor + + /// Default constructor. + /// The value of the map will be uninitialized. + /// (More exactly it will be default constructed.) + ConstMap() {} + + /// Constructor with specified initial value + + /// Constructor with specified initial value. + /// \param _v is the initial value of the map. + ConstMap(const T &_v) : v(_v) {} + + ///\e + T operator[](const K&) const { return v; } + + ///\e + void setAll(const T &t) { + v = t; + } + + template + struct rebind { + typedef ConstMap other; + }; + + template + ConstMap(const ConstMap &, const T &_v) : v(_v) {} + }; + + ///Returns a \c ConstMap class + + ///This function just returns a \c ConstMap class. + ///\relates ConstMap + template + inline ConstMap constMap(const V &v) { + return ConstMap(v); + } + + + template + struct Const { }; + + /// Constant map with inlined constant value. + + /// This is a readable map which assigns a specified value to each key. + /// In other aspects it is equivalent to the \c NullMap. + template + class ConstMap > : public MapBase { + public: + typedef MapBase Parent; + typedef typename Parent::Key Key; + typedef typename Parent::Value Value; + + ConstMap() { } + ///\e + V operator[](const K&) const { return v; } + ///\e + void set(const K&, const V&) { } + }; + + ///Returns a \c ConstMap class + + ///This function just returns a \c ConstMap class with inlined value. + ///\relates ConstMap + template + inline ConstMap > constMap() { + return ConstMap >(); + } + + ///Map based on std::map + + ///This is essentially a wrapper for \c std::map with addition that + ///you can specify a default value different from \c Value(). + template > + class StdMap { + template + friend class StdMap; + public: + + typedef True ReferenceMapTag; + ///\e + typedef K Key; + ///\e + typedef T Value; + ///\e + typedef T& Reference; + ///\e + typedef const T& ConstReference; + + private: + + typedef std::map Map; + Value _value; + Map _map; + + public: + + /// Constructor with specified default value + StdMap(const T& value = T()) : _value(value) {} + /// \brief Constructs the map from an appropriate std::map, and explicitly + /// specifies a default value. + template + StdMap(const std::map &map, const T& value = T()) + : _map(map.begin(), map.end()), _value(value) {} + + /// \brief Constructs a map from an other StdMap. + template + StdMap(const StdMap &c) + : _map(c._map.begin(), c._map.end()), _value(c._value) {} + + private: + + StdMap& operator=(const StdMap&); + + public: + + ///\e + Reference operator[](const Key &k) { + typename Map::iterator it = _map.lower_bound(k); + if (it != _map.end() && !_map.key_comp()(k, it->first)) + return it->second; + else + return _map.insert(it, std::make_pair(k, _value))->second; + } + + /// \e + ConstReference operator[](const Key &k) const { + typename Map::const_iterator it = _map.find(k); + if (it != _map.end()) + return it->second; + else + return _value; + } + + /// \e + void set(const Key &k, const T &t) { + typename Map::iterator it = _map.lower_bound(k); + if (it != _map.end() && !_map.key_comp()(k, it->first)) + it->second = t; + else + _map.insert(it, std::make_pair(k, t)); + } + + /// \e + void setAll(const T &t) { + _value = t; + _map.clear(); + } + + template > + struct rebind { + typedef StdMap other; + }; + }; + + /// \brief Map for storing values for the range \c [0..size-1] range keys + /// + /// The current map has the \c [0..size-1] keyset and the values + /// are stored in a \c std::vector container. It can be used with + /// some data structures, for example \c UnionFind, \c BinHeap, when + /// the used items are small integer numbers. + /// + /// \todo Revise its name + template + class IntegerMap { + + template + friend class IntegerMap; + + public: + + typedef True ReferenceMapTag; + ///\e + typedef int Key; + ///\e + typedef T Value; + ///\e + typedef T& Reference; + ///\e + typedef const T& ConstReference; + + private: + + typedef std::vector Vector; + Vector _vector; + + public: + + /// Constructor with specified default value + IntegerMap(int size = 0, const T& value = T()) : _vector(size, value) {} + + /// \brief Constructs the map from an appropriate std::vector. + template + IntegerMap(const std::vector& vector) + : _vector(vector.begin(), vector.end()) {} + + /// \brief Constructs a map from an other IntegerMap. + template + IntegerMap(const IntegerMap &c) + : _vector(c._vector.begin(), c._vector.end()) {} + + /// \brief Resize the container + void resize(int size, const T& value = T()) { + _vector.resize(size, value); + } + + private: + + IntegerMap& operator=(const IntegerMap&); + + public: + + ///\e + Reference operator[](Key k) { + return _vector[k]; + } + + /// \e + ConstReference operator[](Key k) const { + return _vector[k]; + } + + /// \e + void set(const Key &k, const T& t) { + _vector[k] = t; + } + + }; + + /// @} + + /// \addtogroup map_adaptors + /// @{ + + /// \brief Identity map. + /// + /// This map 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; + + /// \e + const T& operator[](const T& t) const { + return t; + } + }; + + ///Returns an \c IdentityMap class + + ///This function just returns an \c IdentityMap class. + ///\relates IdentityMap + template + inline IdentityMap identityMap() { + return IdentityMap(); + } + + + ///\brief Convert the \c Value of a map to another type using + ///the default conversion. + /// + ///This \c concepts::ReadMap "read only map" + ///converts the \c Value of a map to type \c T. + ///Its \c Key is inherited from \c M. + template + class ConvertMap : public MapBase { + const M& 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. + Value operator[](const Key& k) const {return m[k];} + }; + + ///Returns a \c ConvertMap class + + ///This function just returns a \c ConvertMap class. + ///\relates ConvertMap + template + inline ConvertMap convertMap(const M &m) { + return ConvertMap(m); + } + + ///Simple wrapping of a map + + ///This \c concepts::ReadMap "read only map" returns the simple + ///wrapping of the given map. Sometimes the reference maps cannot be + ///combined with simple read maps. This map adaptor wraps the given + ///map to simple read map. + /// + ///\sa SimpleWriteMap + /// + /// \todo Revise the misleading name + template + class SimpleMap : public MapBase { + const M& m; + + public: + typedef MapBase Parent; + typedef typename Parent::Key Key; + typedef typename Parent::Value Value; + + ///Constructor + SimpleMap(const M &_m) : m(_m) {}; + ///\e + Value operator[](Key k) const {return m[k];} + }; + + ///Simple writable wrapping of the map + + ///This \c concepts::WriteMap "write map" returns the simple + ///wrapping of the given map. Sometimes the reference maps cannot be + ///combined with simple read-write maps. This map adaptor wraps the + ///given map to simple read-write map. + /// + ///\sa SimpleMap + /// + /// \todo Revise the misleading name + template + class SimpleWriteMap : public MapBase { + M& m; + + public: + typedef MapBase Parent; + typedef typename Parent::Key Key; + typedef typename Parent::Value Value; + + ///Constructor + SimpleWriteMap(M &_m) : m(_m) {}; + ///\e + Value operator[](Key k) const {return m[k];} + ///\e + void set(Key k, const Value& c) { m.set(k, c); } + }; + + ///Sum of two maps + + ///This \c concepts::ReadMap "read only map" returns the sum of the two + ///given maps. + ///Its \c Key and \c Value are 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 { + const M1& m1; + const M2& 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) {}; + ///\e + Value operator[](Key k) const {return m1[k]+m2[k];} + }; + + ///Returns an \c AddMap class + + ///This function just returns an \c AddMap class. + ///\todo How to call these type of functions? + /// + ///\relates AddMap + template + inline AddMap addMap(const M1 &m1,const M2 &m2) { + return AddMap(m1,m2); + } + + ///Shift a map with a constant. + + ///This \c concepts::ReadMap "read only map" returns the sum of the + ///given map and a constant value. + ///Its \c Key and \c Value are inherited from \c M. + /// + ///Actually, + ///\code + /// ShiftMap sh(x,v); + ///\endcode + ///is equivalent to + ///\code + /// ConstMap c_tmp(v); + /// AddMap > sh(x,v); + ///\endcode + /// + ///\sa ShiftWriteMap + template + class ShiftMap : public MapBase { + const M& m; + C 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 C &_v ) : m(_m), v(_v) {}; + ///\e + Value operator[](Key k) const {return m[k] + v;} + }; + + ///Shift a map with a constant (ReadWrite version). + + ///This \c concepts::ReadWriteMap "read-write map" returns the sum of the + ///given map and a constant value. It makes also possible to write the map. + ///Its \c Key and \c Value are inherited from \c M. + /// + ///\sa ShiftMap + template + class ShiftWriteMap : public MapBase { + M& m; + C 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. + ShiftWriteMap(M &_m, const C &_v ) : m(_m), v(_v) {}; + /// \e + Value operator[](Key k) const {return m[k] + v;} + /// \e + void set(Key k, const Value& c) { m.set(k, c - v); } + }; + + ///Returns a \c ShiftMap class + + ///This function just returns a \c ShiftMap class. + ///\relates ShiftMap + template + inline ShiftMap shiftMap(const M &m,const C &v) { + return ShiftMap(m,v); + } + + ///Returns a \c ShiftWriteMap class + + ///This function just returns a \c ShiftWriteMap class. + ///\relates ShiftWriteMap + template + inline ShiftWriteMap shiftMap(M &m,const C &v) { + return ShiftWriteMap(m,v); + } + + ///Difference of two maps + + ///This \c concepts::ReadMap "read only map" returns the difference + ///of the values of the two given maps. + ///Its \c Key and \c Value are inherited from \c M1. + ///The \c Key and \c Value of \c M2 must be convertible to those of \c M1. + /// + /// \todo Revise the misleading name + template + class SubMap : public MapBase { + const M1& m1; + const M2& 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) {}; + /// \e + Value operator[](Key k) const {return m1[k]-m2[k];} + }; + + ///Returns a \c SubMap class + + ///This function just returns a \c SubMap class. + /// + ///\relates SubMap + template + inline SubMap subMap(const M1 &m1, const M2 &m2) { + return SubMap(m1, m2); + } + + ///Product of two maps + + ///This \c concepts::ReadMap "read only map" returns the product of the + ///values of the two given maps. + ///Its \c Key and \c Value are 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 { + const M1& m1; + const M2& 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) {}; + /// \e + Value operator[](Key k) const {return m1[k]*m2[k];} + }; + + ///Returns a \c MulMap class + + ///This function just returns a \c MulMap class. + ///\relates MulMap + template + inline MulMap mulMap(const M1 &m1,const M2 &m2) { + return MulMap(m1,m2); + } + + ///Scales a map with a constant. + + ///This \c concepts::ReadMap "read only map" returns the value of the + ///given map multiplied from the left side with a constant value. + ///Its \c Key and \c Value are inherited from \c M. + /// + ///Actually, + ///\code + /// ScaleMap sc(x,v); + ///\endcode + ///is equivalent to + ///\code + /// ConstMap c_tmp(v); + /// MulMap > sc(x,v); + ///\endcode + /// + ///\sa ScaleWriteMap + template + class ScaleMap : public MapBase { + const M& m; + C 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 C &_v ) : m(_m), v(_v) {}; + /// \e + Value operator[](Key k) const {return v * m[k];} + }; + + ///Scales a map with a constant (ReadWrite version). + + ///This \c concepts::ReadWriteMap "read-write map" returns the value of the + ///given map multiplied from the left side with a constant value. It can + ///also be used as write map if the \c / operator is defined between + ///\c Value and \c C and the given multiplier is not zero. + ///Its \c Key and \c Value are inherited from \c M. + /// + ///\sa ScaleMap + template + class ScaleWriteMap : public MapBase { + M& m; + C 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. + ScaleWriteMap(M &_m, const C &_v ) : m(_m), v(_v) {}; + /// \e + Value operator[](Key k) const {return v * m[k];} + /// \e + void set(Key k, const Value& c) { m.set(k, c / v);} + }; + + ///Returns a \c ScaleMap class + + ///This function just returns a \c ScaleMap class. + ///\relates ScaleMap + template + inline ScaleMap scaleMap(const M &m,const C &v) { + return ScaleMap(m,v); + } + + ///Returns a \c ScaleWriteMap class + + ///This function just returns a \c ScaleWriteMap class. + ///\relates ScaleWriteMap + template + inline ScaleWriteMap scaleMap(M &m,const C &v) { + return ScaleWriteMap(m,v); + } + + ///Quotient of two maps + + ///This \c concepts::ReadMap "read only map" returns the quotient of the + ///values of the two given maps. + ///Its \c Key and \c Value are 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 { + const M1& m1; + const M2& 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) {}; + /// \e + Value operator[](Key k) const {return m1[k]/m2[k];} + }; + + ///Returns a \c DivMap class + + ///This function just returns a \c DivMap class. + ///\relates DivMap + template + inline DivMap divMap(const M1 &m1,const M2 &m2) { + return DivMap(m1,m2); + } + + ///Composition of two maps + + ///This \c concepts::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. + ///\c M2::Value must be convertible to \c M1::Key. + /// + ///\sa CombineMap + /// + ///\todo Check the requirements. + template + class ComposeMap : public MapBase { + const M1& m1; + const M2& 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) {}; + + /// \e + + + /// \todo Use the MapTraits once it is ported. + /// + + //typename MapTraits::ConstReturnValue + typename M1::Value + operator[](Key k) const {return m1[m2[k]];} + }; + + ///Returns a \c ComposeMap class + + ///This function just returns a \c 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 \c concepts::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. + ///\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. + /// + ///\sa ComposeMap + /// + ///\todo Check the requirements. + template + class CombineMap : public MapBase { + const M1& m1; + const M2& 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 = F()) + : m1(_m1), m2(_m2), f(_f) {}; + /// \e + Value operator[](Key k) const {return f(m1[k],m2[k]);} + }; + + ///Returns a \c CombineMap class + + ///This function just returns a \c CombineMap class. + /// + ///For example if \c m1 and \c m2 are both \c double valued maps, then + ///\code + ///combineMap(m1,m2,std::plus()) + ///\endcode + ///is equivalent to + ///\code + ///addMap(m1,m2) + ///\endcode + /// + ///This function is specialized for adaptable binary function + ///classes and C++ functions. + /// + ///\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 \c concepts::ReadMap "read only map" returns the negative + ///value of the value returned by the given map. + ///Its \c Key and \c Value are inherited from \c M. + ///The unary \c - operator must be defined for \c Value, of course. + /// + ///\sa NegWriteMap + template + class NegMap : public MapBase { + const M& m; + public: + typedef MapBase Parent; + typedef typename Parent::Key Key; + typedef typename Parent::Value Value; + + ///Constructor + NegMap(const M &_m) : m(_m) {}; + /// \e + Value operator[](Key k) const {return -m[k];} + }; + + ///Negative value of a map (ReadWrite version) + + ///This \c concepts::ReadWriteMap "read-write map" returns the negative + ///value of the value returned by the given map. + ///Its \c Key and \c Value are inherited from \c M. + ///The unary \c - operator must be defined for \c Value, of course. + /// + /// \sa NegMap + template + class NegWriteMap : public MapBase { + M& m; + public: + typedef MapBase Parent; + typedef typename Parent::Key Key; + typedef typename Parent::Value Value; + + ///Constructor + NegWriteMap(M &_m) : m(_m) {}; + /// \e + Value operator[](Key k) const {return -m[k];} + /// \e + void set(Key k, const Value& v) { m.set(k, -v); } + }; + + ///Returns a \c NegMap class + + ///This function just returns a \c NegMap class. + ///\relates NegMap + template + inline NegMap negMap(const M &m) { + return NegMap(m); + } + + ///Returns a \c NegWriteMap class + + ///This function just returns a \c NegWriteMap class. + ///\relates NegWriteMap + template + inline NegWriteMap negMap(M &m) { + return NegWriteMap(m); + } + + ///Absolute value of a map + + ///This \c concepts::ReadMap "read only map" returns the absolute value + ///of the value returned by the given map. + ///Its \c Key and \c Value are inherited from \c M. + ///\c Value must be comparable to \c 0 and the unary \c - + ///operator must be defined for it, of course. + template + class AbsMap : public MapBase { + const M& m; + public: + typedef MapBase Parent; + typedef typename Parent::Key Key; + typedef typename Parent::Value Value; + + ///Constructor + AbsMap(const M &_m) : m(_m) {}; + /// \e + Value operator[](Key k) const { + Value tmp = m[k]; + return tmp >= 0 ? tmp : -tmp; + } + + }; + + ///Returns an \c AbsMap class + + ///This function just returns an \c AbsMap class. + ///\relates AbsMap + template + inline AbsMap absMap(const M &m) { + return AbsMap(m); + } + + ///Converts an STL style functor to a map + + ///This \c concepts::ReadMap "read only map" returns the value + ///of a given functor. + /// + ///Template parameters \c K and \c V will become its + ///\c Key and \c Value. They must be given explicitly + ///because a functor does not provide such typedefs. + /// + ///Parameter \c F is the type of the used functor. + /// + ///\sa MapFunctor + template + class FunctorMap : public MapBase { + F f; + public: + typedef MapBase Parent; + typedef typename Parent::Key Key; + typedef typename Parent::Value Value; + + ///Constructor + FunctorMap(const F &_f = F()) : f(_f) {} + /// \e + Value operator[](Key k) const { return f(k);} + }; + + ///Returns a \c FunctorMap class + + ///This function just returns a \c FunctorMap class. + /// + ///It is specialized for adaptable function classes and + ///C++ functions. + ///\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 \c concepts::ReadMap "readable map", + ///i.e. operator[] and the \c Key and \c Value typedefs also exist. + /// + ///\sa FunctorMap + template + class MapFunctor : public MapBase { + const M& m; + public: + typedef MapBase Parent; + typedef typename Parent::Key Key; + typedef typename Parent::Value Value; + + typedef typename M::Key argument_type; + typedef typename M::Value result_type; + + ///Constructor + MapFunctor(const M &_m) : m(_m) {}; + ///\e + Value operator()(Key k) const {return m[k];} + ///\e + Value operator[](Key k) const {return m[k];} + }; + + ///Returns a \c MapFunctor class + + ///This function just returns a \c 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 \c concepts::ReadMap "readable map" + ///parameters and each read request will be passed just to the + ///first map. This class is the just readable map type of the ForkWriteMap. + /// + ///The \c Key and \c Value are inherited from \c M1. + ///The \c Key and \c Value of M2 must be convertible from those of \c M1. + /// + ///\sa ForkWriteMap + /// + /// \todo Why is it needed? + template + class ForkMap : public MapBase { + const M1& m1; + const M2& 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) {}; + /// \e + Value operator[](Key k) const {return m1[k];} + }; + + + ///Applies all map setting operations to two maps + + ///This map has two \c concepts::WriteMap "writable map" + ///parameters and each write request will be passed to both of them. + ///If \c M1 is also \c concepts::ReadMap "readable", + ///then the read operations will return the + ///corresponding values of \c M1. + /// + ///The \c Key and \c Value are inherited from \c M1. + ///The \c Key and \c Value of M2 must be convertible from those of \c M1. + /// + ///\sa ForkMap + template + class ForkWriteMap : public MapBase { + M1& m1; + M2& m2; + public: + typedef MapBase Parent; + typedef typename Parent::Key Key; + typedef typename Parent::Value Value; + + ///Constructor + ForkWriteMap(M1 &_m1, M2 &_m2) : m1(_m1), m2(_m2) {}; + ///\e + Value operator[](Key k) const {return m1[k];} + ///\e + void set(Key k, const Value &v) {m1.set(k,v); m2.set(k,v);} + }; + + ///Returns a \c ForkMap class + + ///This function just returns a \c ForkMap class. + ///\relates ForkMap + template + inline ForkMap forkMap(const M1 &m1, const M2 &m2) { + return ForkMap(m1,m2); + } + + ///Returns a \c ForkWriteMap class + + ///This function just returns a \c ForkWriteMap class. + ///\relates ForkWriteMap + template + inline ForkWriteMap forkMap(M1 &m1, M2 &m2) { + return ForkWriteMap(m1,m2); + } + + + + /* ************* BOOL MAPS ******************* */ + + ///Logical 'not' of a map + + ///This bool \c concepts::ReadMap "read only map" returns the + ///logical negation of the value returned by the given map. + ///Its \c Key is inherited from \c M, its Value is \c bool. + /// + ///\sa NotWriteMap + template + class NotMap : public MapBase { + const M& m; + public: + typedef MapBase Parent; + typedef typename Parent::Key Key; + typedef typename Parent::Value Value; + + /// Constructor + NotMap(const M &_m) : m(_m) {}; + ///\e + Value operator[](Key k) const {return !m[k];} + }; + + ///Logical 'not' of a map (ReadWrie version) + + ///This bool \c concepts::ReadWriteMap "read-write map" returns the + ///logical negation of the value returned by the given map. When it is set, + ///the opposite value is set to the original map. + ///Its \c Key is inherited from \c M, its Value is \c bool. + /// + ///\sa NotMap + template + class NotWriteMap : public MapBase { + M& m; + public: + typedef MapBase Parent; + typedef typename Parent::Key Key; + typedef typename Parent::Value Value; + + /// Constructor + NotWriteMap(M &_m) : m(_m) {}; + ///\e + Value operator[](Key k) const {return !m[k];} + ///\e + void set(Key k, bool v) { m.set(k, !v); } + }; + + ///Returns a \c NotMap class + + ///This function just returns a \c NotMap class. + ///\relates NotMap + template + inline NotMap notMap(const M &m) { + return NotMap(m); + } + + ///Returns a \c NotWriteMap class + + ///This function just returns a \c NotWriteMap class. + ///\relates NotWriteMap + template + inline NotWriteMap notMap(M &m) { + return NotWriteMap(m); + } + + namespace _maps_bits { + + template + struct Identity { + typedef Value argument_type; + typedef Value result_type; + Value operator()(const Value& val) const { + return val; + } + }; + + template + struct IteratorTraits { + typedef typename std::iterator_traits<_Iterator>::value_type Value; + }; + + template + struct IteratorTraits<_Iterator, + typename exists::type> + { + typedef typename _Iterator::container_type::value_type Value; + }; + + } + + + /// \brief Writable bool map for logging each \c true assigned element + /// + /// Writable bool map for logging each \c true assigned element, i.e it + /// copies all the keys set to \c true to the given iterator. + /// + /// \note The container of the iterator should contain space + /// for each element. + /// + /// The following example shows how you can write the edges found by the Prim + /// algorithm directly + /// to the standard output. + ///\code + /// typedef IdMap EdgeIdMap; + /// EdgeIdMap edgeId(graph); + /// + /// typedef MapFunctor EdgeIdFunctor; + /// EdgeIdFunctor edgeIdFunctor(edgeId); + /// + /// StoreBoolMap, EdgeIdFunctor> + /// writerMap(ostream_iterator(cout, " "), edgeIdFunctor); + /// + /// prim(graph, cost, writerMap); + ///\endcode + /// + ///\sa BackInserterBoolMap + /// + ///\todo Revise the name of this class and the related ones. + template ::Value> > + class StoreBoolMap { + public: + typedef _Iterator Iterator; + + typedef typename _Functor::argument_type Key; + typedef bool Value; + + typedef _Functor Functor; + + /// Constructor + StoreBoolMap(Iterator it, const Functor& functor = Functor()) + : _begin(it), _end(it), _functor(functor) {} + + /// Gives back the given iterator set for the first key + Iterator begin() const { + return _begin; + } + + /// Gives back the the 'after the last' iterator + Iterator end() const { + return _end; + } + + /// The \c set function of the map + void set(const Key& key, Value value) const { + if (value) { + *_end++ = _functor(key); + } + } + + private: + Iterator _begin; + mutable Iterator _end; + Functor _functor; + }; + + /// \brief Writable bool map for logging each \c true assigned element in + /// a back insertable container. + /// + /// Writable bool map for logging each \c true assigned element by pushing + /// them into a back insertable container. + /// It can be used to retrieve the items into a standard + /// container. The next example shows how you can store the + /// edges found by the Prim algorithm in a vector. + /// + ///\code + /// vector span_tree_edges; + /// BackInserterBoolMap > inserter_map(span_tree_edges); + /// prim(graph, cost, inserter_map); + ///\endcode + /// + ///\sa StoreBoolMap + ///\sa FrontInserterBoolMap + ///\sa InserterBoolMap + template > + class BackInserterBoolMap { + public: + typedef typename Container::value_type Key; + typedef bool Value; + + /// Constructor + BackInserterBoolMap(Container& _container, + const Functor& _functor = Functor()) + : container(_container), functor(_functor) {} + + /// The \c set function of the map + void set(const Key& key, Value value) { + if (value) { + container.push_back(functor(key)); + } + } + + private: + Container& container; + Functor functor; + }; + + /// \brief Writable bool map for logging each \c true assigned element in + /// a front insertable container. + /// + /// Writable bool map for logging each \c true assigned element by pushing + /// them into a front insertable container. + /// It can be used to retrieve the items into a standard + /// container. For example see \ref BackInserterBoolMap. + /// + ///\sa BackInserterBoolMap + ///\sa InserterBoolMap + template > + class FrontInserterBoolMap { + public: + typedef typename Container::value_type Key; + typedef bool Value; + + /// Constructor + FrontInserterBoolMap(Container& _container, + const Functor& _functor = Functor()) + : container(_container), functor(_functor) {} + + /// The \c set function of the map + void set(const Key& key, Value value) { + if (value) { + container.push_front(functor(key)); + } + } + + private: + Container& container; + Functor functor; + }; + + /// \brief Writable bool map for storing each \c true assigned element in + /// an insertable container. + /// + /// Writable bool map for storing each \c true assigned element in an + /// insertable container. It will insert all the keys set to \c true into + /// the container. + /// + /// For example, if you want to store the cut arcs of the strongly + /// connected components in a set you can use the next code: + /// + ///\code + /// set cut_arcs; + /// InserterBoolMap > inserter_map(cut_arcs); + /// stronglyConnectedCutArcs(digraph, cost, inserter_map); + ///\endcode + /// + ///\sa BackInserterBoolMap + ///\sa FrontInserterBoolMap + template > + class InserterBoolMap { + public: + typedef typename Container::value_type Key; + typedef bool Value; + + /// Constructor with specified iterator + + /// Constructor with specified iterator. + /// \param _container The container for storing the elements. + /// \param _it The elements will be inserted before this iterator. + /// \param _functor The functor that is used when an element is stored. + InserterBoolMap(Container& _container, typename Container::iterator _it, + const Functor& _functor = Functor()) + : container(_container), it(_it), functor(_functor) {} + + /// Constructor + + /// Constructor without specified iterator. + /// The elements will be inserted before _container.end(). + /// \param _container The container for storing the elements. + /// \param _functor The functor that is used when an element is stored. + InserterBoolMap(Container& _container, const Functor& _functor = Functor()) + : container(_container), it(_container.end()), functor(_functor) {} + + /// The \c set function of the map + void set(const Key& key, Value value) { + if (value) { + it = container.insert(it, functor(key)); + ++it; + } + } + + private: + Container& container; + typename Container::iterator it; + Functor functor; + }; + + /// \brief Writable bool map for filling each \c true assigned element with a + /// given value. + /// + /// Writable bool map for filling each \c true assigned element with a + /// given value. The value can set the container. + /// + /// The following code finds the connected components of a graph + /// and stores it in the \c comp map: + ///\code + /// typedef Graph::NodeMap ComponentMap; + /// ComponentMap comp(graph); + /// typedef FillBoolMap > ComponentFillerMap; + /// ComponentFillerMap filler(comp, 0); + /// + /// Dfs::DefProcessedMap::Create dfs(graph); + /// dfs.processedMap(filler); + /// dfs.init(); + /// for (NodeIt it(graph); it != INVALID; ++it) { + /// if (!dfs.reached(it)) { + /// dfs.addSource(it); + /// dfs.start(); + /// ++filler.fillValue(); + /// } + /// } + ///\endcode + template + class FillBoolMap { + public: + typedef typename Map::Key Key; + typedef bool Value; + + /// Constructor + FillBoolMap(Map& _map, const typename Map::Value& _fill) + : map(_map), fill(_fill) {} + + /// Constructor + FillBoolMap(Map& _map) + : map(_map), fill() {} + + /// Gives back the current fill value + const typename Map::Value& fillValue() const { + return fill; + } + + /// Gives back the current fill value + typename Map::Value& fillValue() { + return fill; + } + + /// Sets the current fill value + void fillValue(const typename Map::Value& _fill) { + fill = _fill; + } + + /// The \c set function of the map + void set(const Key& key, Value value) { + if (value) { + map.set(key, fill); + } + } + + private: + Map& map; + typename Map::Value fill; + }; + + + /// \brief Writable bool map for storing the sequence number of + /// \c true assignments. + /// + /// Writable bool map that stores for each \c true assigned elements + /// the sequence number of this setting. + /// It makes it easy to calculate the leaving + /// order of the nodes in the \c Dfs algorithm. + /// + ///\code + /// typedef Digraph::NodeMap OrderMap; + /// OrderMap order(digraph); + /// typedef SettingOrderBoolMap OrderSetterMap; + /// OrderSetterMap setter(order); + /// Dfs::DefProcessedMap::Create dfs(digraph); + /// dfs.processedMap(setter); + /// dfs.init(); + /// for (NodeIt it(digraph); it != INVALID; ++it) { + /// if (!dfs.reached(it)) { + /// dfs.addSource(it); + /// dfs.start(); + /// } + /// } + ///\endcode + /// + /// The storing of the discovering order is more difficult because the + /// ReachedMap should be readable in the dfs algorithm but the setting + /// order map is not readable. Thus we must use the fork map: + /// + ///\code + /// typedef Digraph::NodeMap OrderMap; + /// OrderMap order(digraph); + /// typedef SettingOrderBoolMap OrderSetterMap; + /// OrderSetterMap setter(order); + /// typedef Digraph::NodeMap StoreMap; + /// StoreMap store(digraph); + /// + /// typedef ForkWriteMap ReachedMap; + /// ReachedMap reached(store, setter); + /// + /// Dfs::DefReachedMap::Create dfs(digraph); + /// dfs.reachedMap(reached); + /// dfs.init(); + /// for (NodeIt it(digraph); it != INVALID; ++it) { + /// if (!dfs.reached(it)) { + /// dfs.addSource(it); + /// dfs.start(); + /// } + /// } + ///\endcode + template + class SettingOrderBoolMap { + public: + typedef typename Map::Key Key; + typedef bool Value; + + /// Constructor + SettingOrderBoolMap(Map& _map) + : map(_map), counter(0) {} + + /// Number of set operations. + int num() const { + return counter; + } + + /// Setter function of the map + void set(const Key& key, Value value) { + if (value) { + map.set(key, counter++); + } + } + + private: + Map& map; + int counter; + }; + + /// @} +} + +#endif // LEMON_MAPS_H diff --git a/test/maps_test.cc b/test/maps_test.cc new file mode 100644 --- /dev/null +++ b/test/maps_test.cc @@ -0,0 +1,108 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2007 + * 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. + * + */ + +#include +#include + +#include +#include +#include + +#include "test_tools.h" + +using namespace lemon; +using namespace lemon::concepts; + +struct A {}; +inline bool operator<(A, A) { return true; } +struct B {}; + +class F { +public: + typedef A argument_type; + typedef B result_type; + + B operator()(const A &) const {return B();} +}; + +int func(A) {return 3;} + +int binc(int, B) {return 4;} + +typedef ReadMap DoubleMap; +typedef ReadWriteMap WriteDoubleMap; + +typedef ReadMap BoolMap; +typedef ReadWriteMap BoolWriteMap; + +int main() +{ // checking graph components + + checkConcept, ReadMap >(); + checkConcept, WriteMap >(); + checkConcept, ReadWriteMap >(); + checkConcept, ReferenceMap >(); + + checkConcept, AddMap >(); + checkConcept, SubMap >(); + checkConcept, MulMap >(); + checkConcept, DivMap >(); + checkConcept, NegMap >(); + checkConcept, NegWriteMap >(); + checkConcept, AbsMap >(); + checkConcept, ShiftMap >(); + checkConcept, ShiftWriteMap >(); + checkConcept, ScaleMap >(); + checkConcept, ScaleWriteMap >(); + checkConcept, ForkMap >(); + checkConcept, + ForkWriteMap >(); + + checkConcept, ComposeMap > >(); + + checkConcept, FunctorMap >(); + + checkConcept, NotMap >(); + checkConcept, NotWriteMap >(); + + checkConcept, StoreBoolMap >(); + checkConcept, BackInserterBoolMap > >(); + checkConcept, FrontInserterBoolMap > >(); + checkConcept, InserterBoolMap > >(); + checkConcept, FillBoolMap > >(); + checkConcept, SettingOrderBoolMap > >(); + + int a; + + a=mapFunctor(constMap(2))(A()); + check(a==2,"Something is wrong with mapFunctor"); + + B b; + b=functorMap(F())[A()]; + + a=functorMap(&func)[A()]; + check(a==3,"Something is wrong with functorMap"); + + a=combineMap(constMap(), identityMap(), &binc)[B()]; + check(a==4,"Something is wrong with combineMap"); + + + std::cout << __FILE__ ": All tests passed.\n"; + + return 0; +}