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