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 <lemon/concept_check.h>
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<typename K, typename T>
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<typename K, typename T>
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<typename K, typename T>
alpar@732:     class ReadWriteMap : public ReadMap<K,T>,
alpar@732: 			    public WriteMap<K,T>
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<typename K, typename T>
alpar@732:     class ReferenceMap : public ReadWriteMap<K,T>
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<typename Item, typename T, typename Graph>
klao@946:     class GraphMap : public ReadWriteMap<Item, T> {
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<typename TT>
klao@946:       // GraphMap(GraphMap<TT> const&);
klao@946:       //
klao@946:       // template<typename TT>
klao@946:       // GraphMap& operator=(const GraphMap<TT>&);
klao@946:     };
klao@946: 
klao@946: 
klao@946:     /****************  Concept-checking classes  ****************/
klao@946: 
klao@946:     template<typename ReadMap>
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<typename WriteMap>
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<typename ReadWriteMap>
klao@946:     struct ReadWriteMapConcept {
klao@946:       void constraints() {
klao@946: 	function_requires< ReadMapConcept<ReadWriteMap> >();
klao@946: 	function_requires< WriteMapConcept<ReadWriteMap> >();
klao@946:       }
klao@946:     };
klao@946: 
klao@946:     template<typename ReferenceMap>
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<ReferenceMap> >();
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<typename GraphMap, typename Graph>
klao@946:     struct GraphMapConcept {
klao@946:       void constraints() {
klao@946: 	function_requires< ReadWriteMapConcept<GraphMap> >();
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