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. klao@959: typedef K KeyType; klao@959: /// Map's value type. (The type of objects associated with the keys). klao@959: typedef T ValueType; klao@959: klao@959: /// Returns the value associated with a key. klao@959: ValueType operator[](const KeyType &k) const {return ValueType();} 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. klao@959: typedef K KeyType; klao@959: /// Map's value type. (The type of objects associated with the keys). klao@959: typedef T ValueType; klao@959: klao@959: /// Sets the value associated with a key. klao@959: void set(const KeyType &k,const ValueType &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. klao@959: typedef K KeyType; klao@959: /// Map's value type. (The type of objects associated with the keys). klao@959: typedef T ValueType; klao@959: klao@959: /// Returns the value associated with a key. klao@959: ValueType operator[](const KeyType &k) const {return ValueType();} klao@959: /// Sets the value associated with a key. klao@959: void set(const KeyType &k,const ValueType &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. klao@959: typedef K KeyType; klao@959: /// Map's value type. (The type of objects associated with the keys). klao@959: typedef T ValueType; klao@959: klao@959: protected: klao@959: ValueType tmp; klao@959: public: klao@959: typedef ValueType& ReferenceType; klao@959: /// Map's const reference type. klao@959: typedef const ValueType& ConstReferenceType; klao@959: klao@959: ///Returns a reference to the value associated to a key. klao@959: ReferenceType operator[](const KeyType &i) { return tmp; } klao@959: ///Returns a const reference to the value associated to a key. klao@959: ConstReferenceType operator[](const KeyType &i) const klao@959: { return tmp; } klao@959: /// Sets the value associated with a key. klao@959: void set(const KeyType &k,const ValueType &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 { klao@959: typedef typename ReadMap::KeyType KeyType; klao@959: typedef typename ReadMap::ValueType ValueType; klao@959: klao@959: void constraints() { klao@959: // No constraints for constructor. klao@959: klao@959: // What are the requirement for the ValueType? klao@959: // CopyConstructible? Assignable? None of these? klao@959: ValueType 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; klao@959: KeyType k; klao@959: }; klao@959: klao@959: template klao@959: struct WriteMapConcept { klao@959: typedef typename WriteMap::KeyType KeyType; klao@959: typedef typename WriteMap::ValueType ValueType; 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; klao@959: KeyType k; klao@959: ValueType 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 { klao@959: typedef typename ReferenceMap::KeyType KeyType; klao@959: typedef typename ReferenceMap::ValueType ValueType; klao@959: typedef typename ReferenceMap::ReferenceType ReferenceType; klao@959: klao@959: // What for is this? klao@959: typedef typename ReferenceMap::ConstReferenceType ConstReferenceType; 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: klao@959: // ValueType &vv = m[k]; klao@959: // ignore_unused_variable_warning(vv); klao@959: } klao@959: klao@959: ReferenceMap m; klao@959: KeyType k; klao@959: ValueType 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; klao@959: const typename GraphMap::ValueType &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