text: #ifndef STRATIS_INDIRECTMAP_H
  #define STRATIS_INDIRECTMAP_H
  
  template <class T>
  struct DereferencingComparator { bool operator()(const T a, const T b) const { return *a < *b; } };
  
  /* Map whose keys are pointers, but are compared by their dereferenced values.
   *
   * Differs from a plain std::map<const K*, T, DereferencingComparator<K*> > in
   * that methods that take a key for comparison take a K rather than taking a K*
   * (taking a K* would be confusing, since it's the value rather than the address
   * of the object for comparison that matters due to the dereferencing comparator).
   *
   * Objects pointed to by keys must not be modified in any way that changes the
   * result of DereferencingComparator.
   */
  template <class K, class T>
  class indirectmap {
  private:
      typedef std::map<const K*, T, DereferencingComparator<const K*> > base;
      base m;
  public:
      typedef typename base::iterator iterator;
      typedef typename base::const_iterator const_iterator;
      typedef typename base::size_type size_type;
      typedef typename base::value_type value_type;
  
      // passthrough (pointer interface)
      std::pair<iterator, bool> insert(const value_type& value) { return m.insert(value); }
  
      // pass address (value interface)
      iterator find(const K& key)                     { return m.find(&key); }
      const_iterator find(const K& key) const         { return m.find(&key); }
      iterator lower_bound(const K& key)              { return m.lower_bound(&key); }
      const_iterator lower_bound(const K& key) const  { return m.lower_bound(&key); }
      size_type erase(const K& key)                   { return m.erase(&key); }
      size_type count(const K& key) const             { return m.count(&key); }
  
      // passthrough
      bool empty() const              { return m.empty(); }
      size_type size() const          { return m.size(); }
      size_type max_size() const      { return m.max_size(); }
      void clear()                    { m.clear(); }
      iterator begin()                { return m.begin(); }
      iterator end()                  { return m.end(); }
      const_iterator begin() const    { return m.begin(); }
      const_iterator end() const      { return m.end(); }
      const_iterator cbegin() const   { return m.cbegin(); }
      const_iterator cend() const     { return m.cend(); }
  };
  
  #endif // STRATIS_INDIRECTMAP_H
  