alpar@906: /* -*- C++ -*- alpar@921: * src/lemon/skeletons/maps.h - Part of LEMON, a generic C++ optimization library alpar@906: * alpar@906: * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport alpar@906: * (Egervary Combinatorial Optimization Research Group, EGRES). alpar@906: * alpar@906: * Permission to use, modify and distribute this software is granted alpar@906: * provided that this copyright notice appears in all copies. For alpar@906: * precise terms see the accompanying LICENSE file. alpar@906: * alpar@906: * This software is provided "AS IS" with no warranty of any kind, alpar@906: * express or implied, and with no claim as to its suitability for any alpar@906: * purpose. alpar@906: * alpar@906: */ alpar@906: alpar@921: #ifndef LEMON_MAPSKELETON_H alpar@921: #define LEMON_MAPSKELETON_H alpar@186: klao@946: #include klao@946: alpar@794: ///\ingroup skeletons alpar@242: ///\file alpar@242: ///\brief Map concepts checking classes for testing and documenting. alpar@242: alpar@921: namespace lemon { klao@282: klao@282: namespace skeleton { alpar@186: alpar@794: /// \addtogroup skeletons alpar@794: /// @{ alpar@794: klao@282: /// Readable map concept klao@282: template alpar@732: class ReadMap klao@282: { klao@282: public: klao@282: /// Map's key type. klao@282: typedef K KeyType; klao@282: /// Map's value type. (The type of objects associated with the keys). klao@282: typedef T ValueType; alpar@186: klao@282: /// Returns the value associated with a key. klao@282: ValueType operator[](const KeyType &k) const {return ValueType();} alpar@186: alpar@732: ///Default constructor alpar@732: ReadMap() {} klao@282: }; klao@282: klao@282: klao@282: /// Writable map concept klao@282: template alpar@732: class WriteMap klao@282: { klao@282: public: klao@282: /// Map's key type. klao@282: typedef K KeyType; klao@282: /// Map's value type. (The type of objects associated with the keys). klao@282: typedef T ValueType; klao@282: klao@282: /// Sets the value associated with a key. klao@282: void set(const KeyType &k,const ValueType &t) {} klao@282: alpar@732: ///Default constructor alpar@732: WriteMap() {} klao@282: }; klao@282: alpar@809: ///Read/Writable map concept klao@282: template alpar@732: class ReadWriteMap : public ReadMap, alpar@732: public WriteMap klao@282: { klao@282: public: klao@282: /// Map's key type. klao@282: typedef K KeyType; klao@282: /// Map's value type. (The type of objects associated with the keys). klao@282: typedef T ValueType; klao@282: klao@282: /// Returns the value associated with a key. klao@282: ValueType operator[](const KeyType &k) const {return ValueType();} klao@282: /// Sets the value associated with a key. klao@282: void set(const KeyType &k,const ValueType &t) {} klao@282: alpar@732: ///Default constructor alpar@732: ReadWriteMap() {} klao@282: }; alpar@186: alpar@186: klao@282: ///Dereferable map concept klao@282: template alpar@732: class ReferenceMap : public ReadWriteMap klao@282: { klao@282: public: klao@282: /// Map's key type. klao@282: typedef K KeyType; klao@282: /// Map's value type. (The type of objects associated with the keys). klao@282: typedef T ValueType; alpar@732: alpar@732: protected: alpar@732: ValueType tmp; alpar@732: public: klao@282: typedef ValueType& ReferenceType; klao@282: /// Map's const reference type. klao@282: typedef const ValueType& ConstReferenceType; alpar@186: klao@282: ///Returns a reference to the value associated to a key. alpar@732: ReferenceType operator[](const KeyType &i) { return tmp; } klao@282: ///Returns a const reference to the value associated to a key. alpar@732: ConstReferenceType operator[](const KeyType &i) const alpar@732: { return tmp; } klao@282: /// Sets the value associated with a key. klao@282: void set(const KeyType &k,const ValueType &t) { operator[](k)=t; } alpar@186: alpar@732: ///Default constructor alpar@732: ReferenceMap() {} klao@282: }; alpar@794: klao@946: klao@946: template klao@946: class GraphMap : public ReadWriteMap { klao@946: // I really, really don't like the idea that every graph should have klao@946: // reference maps! --klao klao@946: klao@946: private: klao@946: // We state explicitly that graph maps have no default constructor? klao@946: GraphMap(); klao@946: klao@946: public: klao@946: explicit GraphMap(Graph const&) {} klao@946: // value for initializing klao@946: GraphMap(Graph const&, T) {} klao@946: klao@946: // this probably should be required: klao@946: GraphMap(GraphMap const&) {} klao@946: GraphMap& operator=(GraphMap const&) { return *this; } klao@946: klao@946: // but this is a absolute no-op! We should provide a more generic klao@946: // graph-map-copy operation. klao@946: // klao@946: // template klao@946: // GraphMap(GraphMap const&); klao@946: // klao@946: // template klao@946: // GraphMap& operator=(const GraphMap&); klao@946: }; klao@946: klao@946: klao@946: /**************** Concept-checking classes ****************/ klao@946: klao@946: template klao@946: struct ReadMapConcept { klao@946: typedef typename ReadMap::KeyType KeyType; klao@946: typedef typename ReadMap::ValueType ValueType; klao@946: klao@946: void constraints() { klao@946: // No constraints for constructor. klao@946: klao@946: // What are the requirement for the ValueType? klao@946: // CopyConstructible? Assignable? None of these? klao@946: ValueType v = m[k]; klao@946: v = m[k]; klao@946: klao@946: // FIXME: klao@946: ignore_unused_variable_warning(v); klao@946: } klao@946: klao@946: ReadMap m; klao@946: KeyType k; klao@946: }; klao@946: klao@946: template klao@946: struct WriteMapConcept { klao@946: typedef typename WriteMap::KeyType KeyType; klao@946: typedef typename WriteMap::ValueType ValueType; klao@946: klao@946: void constraints() { klao@946: // No constraints for constructor. klao@946: klao@946: m.set(k, v); klao@946: } klao@946: klao@946: WriteMap m; klao@946: KeyType k; klao@946: ValueType v; klao@946: }; klao@946: klao@946: template klao@946: struct ReadWriteMapConcept { klao@946: void constraints() { klao@946: function_requires< ReadMapConcept >(); klao@946: function_requires< WriteMapConcept >(); klao@946: } klao@946: }; klao@946: klao@946: template klao@946: struct ReferenceMapConcept { klao@946: typedef typename ReferenceMap::KeyType KeyType; klao@946: typedef typename ReferenceMap::ValueType ValueType; klao@946: typedef typename ReferenceMap::ReferenceType ReferenceType; klao@946: klao@946: // What for is this? klao@946: typedef typename ReferenceMap::ConstReferenceType ConstReferenceType; klao@946: klao@946: void constraints() { klao@946: function_requires< ReadWriteMapConcept >(); klao@946: klao@946: m[k] = v; klao@946: // Or should we require real reference? klao@946: // Like this: klao@946: // ValueType &vv = m[k]; klao@946: // ignore_unused_variable_warning(vv); klao@946: } klao@946: klao@946: ReferenceMap m; klao@946: KeyType k; klao@946: ValueType v; klao@946: }; klao@946: klao@946: /// \todo GraphMapConceptCheck klao@946: klao@946: template klao@946: struct GraphMapConcept { klao@946: void constraints() { klao@946: function_requires< ReadWriteMapConcept >(); klao@946: // Construction with a graph parameter klao@946: GraphMap a(g); klao@946: // Ctor with a graph and a default value parameter klao@946: GraphMap a2(g,t); klao@946: // Copy ctor. Do we need it? klao@946: GraphMap b=c; klao@946: // Copy operator. Do we need it? klao@946: a=b; klao@946: klao@946: ignore_unused_variable_warning(a2); klao@946: } klao@946: const GraphMap &c; klao@946: const Graph &g; klao@946: const typename GraphMap::ValueType &t; klao@946: }; klao@946: klao@946: alpar@794: // @} alpar@794: alpar@732: } //namespace skeleton alpar@921: } //namespace lemon alpar@921: #endif // LEMON_MAPSKELETON_H