klao@286: // -*- C++ -*- //
klao@286: #ifndef HUGO_MAPS_H
klao@286: #define HUGO_MAPS_H
klao@286: 
klao@286: ///\file
klao@286: ///\brief Miscellaneous property maps
klao@286: ///
klao@286: ///\todo This file has the same name as the concept file in skeletons,
klao@286: /// and this is not easily detectable in docs...
klao@286: 
klao@286: #include <map>
klao@286: 
klao@286: namespace hugo {
klao@286: 
klao@286:   /// Null map. (aka DoNothingMap)
klao@286: 
klao@286:   /// If you have to provide a map only for its type definitions,
klao@286:   /// or if you have to provide a writable map, but will not use the
klao@286:   /// data written to it...
klao@286:   template<typename K, typename T>
klao@286:   class NullMap
klao@286:   {
klao@286:   public:
klao@286:     typedef K KeyType;
klao@286:     typedef T ValueType;
klao@286: 
klao@286:     T operator[](const K&) const { return T(); }
klao@286:     void set(const K&, const T&) {}
klao@286:   };
klao@286: 
klao@286: 
klao@286:   /// Constant map.
klao@286: 
klao@286:   /// This is a readable map which assignes a specified value to each key.
klao@286:   /// In other aspects it is equivalent to the \ref NullMap
klao@286:   template<typename K, typename T>
klao@286:   class ConstMap
klao@286:   {
klao@286:     T v;
klao@286:   public:
klao@286:     typedef K KeyType;
klao@286:     typedef T ValueType;
klao@286: 
klao@286:     ConstMap() {}
klao@286:     ConstMap(const T &_v) : v(_v) {}
klao@286: 
klao@286:     T operator[](const K&) const { return v; }
klao@286:     void set(const K&, const T&) {}
klao@286: 
klao@286:     template<typename T1>
klao@286:     struct rebind {
klao@286:       typedef ConstMap<K,T1> other;
klao@286:     };
klao@286: 
klao@286:     template<typename T1>
klao@286:     ConstMap(const ConstMap<K,T1> &, const T &_v) : v(_v) {}
klao@286:   };
klao@286: 
klao@286: 
klao@286: 
klao@286:   /// \c std::map wrapper
klao@286: 
klao@286:   /// This is essentially a wrapper for \c std::map. With addition that
klao@286:   /// you can specify a default value different from \c ValueType() .
klao@286:   ///
klao@286:   /// \todo Provide allocator parameter...
klao@286:   template <typename Key, typename T, typename Compare = std::less<Key> >
klao@286:   class StdMap : public std::map<Key,T,Compare> {
klao@286:     typedef std::map<Key,T,Compare> parent;
klao@286:     T v;
klao@286:     typedef typename parent::value_type PairType;
klao@286: 
klao@286:   public:
klao@286:     typedef Key KeyType;
klao@286:     typedef T ValueType;
klao@286:     typedef T& ReferenceType;
klao@286:     typedef const T& ConstReferenceType;
klao@286: 
klao@286: 
klao@286:     StdMap() {}
klao@286:     /// Constructor with specified default value
klao@286:     StdMap(const T& _v) : v(_v) {}
klao@286: 
klao@286:     /// \brief Constructs the map from an appropriate std::map.
klao@286:     ///
klao@286:     /// \warning Inefficient: copies the content of \c m !
klao@286:     StdMap(const parent &m) : parent(m) {}
klao@286:     /// \brief Constructs the map from an appropriate std::map, and explicitly
klao@286:     /// specifies a default value.
klao@286:     ///
klao@286:     /// \warning Inefficient: copies the content of \c m !
klao@286:     StdMap(const parent &m, const T& _v) : parent(m), v(_v) {}
klao@286:     
klao@286:     template<typename T1, typename Comp1>
klao@286:     StdMap(const StdMap<Key,T1,Comp1> &m, const T &_v) { FIXME; }
klao@286: 
klao@286:     ReferenceType operator[](const Key &k) {
klao@286:       return (  *( (insert(PairType(k,v))).first )  ).second;
klao@286:     }
klao@286:     ConstReferenceType operator[](const Key &k) const {
klao@286:       typename parent::iterator i = lower_bound(__k);
klao@286:       if (i == end() || key_comp()(k, (*i).first))
klao@286: 	return v;
klao@286:       return (*i).second;
klao@286:     }
klao@286:     void set(const Key &k, const T &t) { parent::operator[](k)=t; }
klao@286: 
klao@286:     /// Changes the default value of the map.
klao@286:     /// \return Returns the previous default value.
klao@286:     ///
klao@286:     /// \warning The value of some keys (which has alredy been queried, but
klao@286:     /// the value has been unchanged from the default) may change!
klao@286:     T setDefault(const T &_v) { T old=v; v=_v; return old; }
klao@286: 
klao@286:     template<typename T1>
klao@286:     struct rebind {
klao@286:       typedef StdMap<Key,T1,Compare> other;
klao@286:     };
klao@286:   };
klao@286:   
klao@286: }
klao@286: #endif // HUGO_MAPS_H