alpar@209: /* -*- mode: C++; indent-tabs-mode: nil; -*-
deba@57:  *
alpar@209:  * This file is a part of LEMON, a generic C++ optimization library.
deba@57:  *
alpar@107:  * Copyright (C) 2003-2008
deba@57:  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@57:  * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@57:  *
deba@57:  * Permission to use, modify and distribute this software is granted
deba@57:  * provided that this copyright notice appears in all copies. For
deba@57:  * precise terms see the accompanying LICENSE file.
deba@57:  *
deba@57:  * This software is provided "AS IS" with no warranty of any kind,
deba@57:  * express or implied, and with no claim as to its suitability for any
deba@57:  * purpose.
deba@57:  *
deba@57:  */
deba@57: 
deba@57: #ifndef LEMON_BITS_MAP_EXTENDER_H
deba@57: #define LEMON_BITS_MAP_EXTENDER_H
deba@57: 
deba@57: #include <iterator>
deba@57: 
deba@57: #include <lemon/bits/traits.h>
deba@57: 
deba@57: #include <lemon/concept_check.h>
deba@57: #include <lemon/concepts/maps.h>
deba@57: 
kpeter@314: //\file
kpeter@314: //\brief Extenders for iterable maps.
deba@57: 
deba@57: namespace lemon {
deba@57: 
kpeter@314:   // \ingroup graphbits
kpeter@314:   //
kpeter@314:   // \brief Extender for maps
deba@57:   template <typename _Map>
deba@57:   class MapExtender : public _Map {
deba@57:   public:
deba@57: 
deba@57:     typedef _Map Parent;
deba@57:     typedef MapExtender Map;
deba@57: 
deba@57: 
deba@57:     typedef typename Parent::Graph Graph;
deba@57:     typedef typename Parent::Key Item;
deba@57: 
deba@57:     typedef typename Parent::Key Key;
deba@57:     typedef typename Parent::Value Value;
deba@57: 
deba@57:     class MapIt;
deba@57:     class ConstMapIt;
deba@57: 
deba@57:     friend class MapIt;
deba@57:     friend class ConstMapIt;
deba@57: 
deba@57:   public:
deba@57: 
alpar@209:     MapExtender(const Graph& graph)
deba@57:       : Parent(graph) {}
deba@57: 
alpar@209:     MapExtender(const Graph& graph, const Value& value)
deba@57:       : Parent(graph, value) {}
deba@57: 
kpeter@263:   private:
deba@57:     MapExtender& operator=(const MapExtender& cmap) {
deba@57:       return operator=<MapExtender>(cmap);
deba@57:     }
deba@57: 
deba@57:     template <typename CMap>
deba@57:     MapExtender& operator=(const CMap& cmap) {
deba@57:       Parent::operator=(cmap);
deba@57:       return *this;
alpar@209:     }
deba@57: 
kpeter@263:   public:
deba@57:     class MapIt : public Item {
deba@57:     public:
alpar@209: 
deba@57:       typedef Item Parent;
deba@57:       typedef typename Map::Value Value;
alpar@209: 
deba@57:       MapIt() {}
deba@57: 
deba@57:       MapIt(Invalid i) : Parent(i) { }
deba@57: 
deba@57:       explicit MapIt(Map& _map) : map(_map) {
deba@57:         map.notifier()->first(*this);
deba@57:       }
deba@57: 
alpar@209:       MapIt(const Map& _map, const Item& item)
alpar@209:         : Parent(item), map(_map) {}
deba@57: 
alpar@209:       MapIt& operator++() {
alpar@209:         map.notifier()->next(*this);
alpar@209:         return *this;
deba@57:       }
alpar@209: 
deba@57:       typename MapTraits<Map>::ConstReturnValue operator*() const {
alpar@209:         return map[*this];
deba@57:       }
deba@57: 
deba@57:       typename MapTraits<Map>::ReturnValue operator*() {
alpar@209:         return map[*this];
deba@57:       }
alpar@209: 
deba@57:       void set(const Value& value) {
alpar@209:         map.set(*this, value);
deba@57:       }
alpar@209: 
deba@57:     protected:
deba@57:       Map& map;
alpar@209: 
deba@57:     };
deba@57: 
deba@57:     class ConstMapIt : public Item {
deba@57:     public:
deba@57: 
deba@57:       typedef Item Parent;
deba@57: 
deba@57:       typedef typename Map::Value Value;
alpar@209: 
deba@57:       ConstMapIt() {}
deba@57: 
deba@57:       ConstMapIt(Invalid i) : Parent(i) { }
deba@57: 
deba@57:       explicit ConstMapIt(Map& _map) : map(_map) {
deba@57:         map.notifier()->first(*this);
deba@57:       }
deba@57: 
alpar@209:       ConstMapIt(const Map& _map, const Item& item)
alpar@209:         : Parent(item), map(_map) {}
deba@57: 
alpar@209:       ConstMapIt& operator++() {
alpar@209:         map.notifier()->next(*this);
alpar@209:         return *this;
deba@57:       }
deba@57: 
deba@57:       typename MapTraits<Map>::ConstReturnValue operator*() const {
alpar@209:         return map[*this];
deba@57:       }
deba@57: 
deba@57:     protected:
deba@57:       const Map& map;
deba@57:     };
deba@57: 
deba@57:     class ItemIt : public Item {
deba@57:     public:
alpar@209: 
deba@57:       typedef Item Parent;
alpar@209: 
deba@57:       ItemIt() {}
deba@57: 
deba@57:       ItemIt(Invalid i) : Parent(i) { }
deba@57: 
deba@57:       explicit ItemIt(Map& _map) : map(_map) {
deba@57:         map.notifier()->first(*this);
deba@57:       }
deba@57: 
alpar@209:       ItemIt(const Map& _map, const Item& item)
alpar@209:         : Parent(item), map(_map) {}
deba@57: 
alpar@209:       ItemIt& operator++() {
alpar@209:         map.notifier()->next(*this);
alpar@209:         return *this;
deba@57:       }
deba@57: 
deba@57:     protected:
deba@57:       const Map& map;
alpar@209: 
deba@57:     };
deba@57:   };
deba@57: 
kpeter@314:   // \ingroup graphbits
kpeter@314:   //
kpeter@314:   // \brief Extender for maps which use a subset of the items.
deba@57:   template <typename _Graph, typename _Map>
deba@57:   class SubMapExtender : public _Map {
deba@57:   public:
deba@57: 
deba@57:     typedef _Map Parent;
deba@57:     typedef SubMapExtender Map;
deba@57: 
deba@57:     typedef _Graph Graph;
deba@57: 
deba@57:     typedef typename Parent::Key Item;
deba@57: 
deba@57:     typedef typename Parent::Key Key;
deba@57:     typedef typename Parent::Value Value;
deba@57: 
deba@57:     class MapIt;
deba@57:     class ConstMapIt;
deba@57: 
deba@57:     friend class MapIt;
deba@57:     friend class ConstMapIt;
deba@57: 
deba@57:   public:
deba@57: 
alpar@209:     SubMapExtender(const Graph& _graph)
deba@57:       : Parent(_graph), graph(_graph) {}
deba@57: 
alpar@209:     SubMapExtender(const Graph& _graph, const Value& _value)
deba@57:       : Parent(_graph, _value), graph(_graph) {}
deba@57: 
kpeter@263:   private:
deba@57:     SubMapExtender& operator=(const SubMapExtender& cmap) {
deba@57:       return operator=<MapExtender>(cmap);
deba@57:     }
deba@57: 
deba@57:     template <typename CMap>
deba@57:     SubMapExtender& operator=(const CMap& cmap) {
deba@57:       checkConcept<concepts::ReadMap<Key, Value>, CMap>();
deba@57:       Item it;
deba@57:       for (graph.first(it); it != INVALID; graph.next(it)) {
deba@57:         Parent::set(it, cmap[it]);
deba@57:       }
deba@57:       return *this;
alpar@209:     }
deba@57: 
kpeter@263:   public:
deba@57:     class MapIt : public Item {
deba@57:     public:
alpar@209: 
deba@57:       typedef Item Parent;
deba@57:       typedef typename Map::Value Value;
alpar@209: 
deba@57:       MapIt() {}
deba@57: 
deba@57:       MapIt(Invalid i) : Parent(i) { }
deba@57: 
deba@57:       explicit MapIt(Map& _map) : map(_map) {
deba@57:         map.graph.first(*this);
deba@57:       }
deba@57: 
alpar@209:       MapIt(const Map& _map, const Item& item)
alpar@209:         : Parent(item), map(_map) {}
deba@57: 
alpar@209:       MapIt& operator++() {
alpar@209:         map.graph.next(*this);
alpar@209:         return *this;
deba@57:       }
alpar@209: 
deba@57:       typename MapTraits<Map>::ConstReturnValue operator*() const {
alpar@209:         return map[*this];
deba@57:       }
deba@57: 
deba@57:       typename MapTraits<Map>::ReturnValue operator*() {
alpar@209:         return map[*this];
deba@57:       }
alpar@209: 
deba@57:       void set(const Value& value) {
alpar@209:         map.set(*this, value);
deba@57:       }
alpar@209: 
deba@57:     protected:
deba@57:       Map& map;
alpar@209: 
deba@57:     };
deba@57: 
deba@57:     class ConstMapIt : public Item {
deba@57:     public:
deba@57: 
deba@57:       typedef Item Parent;
deba@57: 
deba@57:       typedef typename Map::Value Value;
alpar@209: 
deba@57:       ConstMapIt() {}
deba@57: 
deba@57:       ConstMapIt(Invalid i) : Parent(i) { }
deba@57: 
deba@57:       explicit ConstMapIt(Map& _map) : map(_map) {
deba@57:         map.graph.first(*this);
deba@57:       }
deba@57: 
alpar@209:       ConstMapIt(const Map& _map, const Item& item)
alpar@209:         : Parent(item), map(_map) {}
deba@57: 
alpar@209:       ConstMapIt& operator++() {
alpar@209:         map.graph.next(*this);
alpar@209:         return *this;
deba@57:       }
deba@57: 
deba@57:       typename MapTraits<Map>::ConstReturnValue operator*() const {
alpar@209:         return map[*this];
deba@57:       }
deba@57: 
deba@57:     protected:
deba@57:       const Map& map;
deba@57:     };
deba@57: 
deba@57:     class ItemIt : public Item {
deba@57:     public:
alpar@209: 
deba@57:       typedef Item Parent;
alpar@209: 
deba@57:       ItemIt() {}
deba@57: 
deba@57:       ItemIt(Invalid i) : Parent(i) { }
deba@57: 
deba@57:       explicit ItemIt(Map& _map) : map(_map) {
deba@57:         map.graph.first(*this);
deba@57:       }
deba@57: 
alpar@209:       ItemIt(const Map& _map, const Item& item)
alpar@209:         : Parent(item), map(_map) {}
deba@57: 
alpar@209:       ItemIt& operator++() {
alpar@209:         map.graph.next(*this);
alpar@209:         return *this;
deba@57:       }
deba@57: 
deba@57:     protected:
deba@57:       const Map& map;
alpar@209: 
deba@57:     };
alpar@209: 
deba@57:   private:
deba@57: 
deba@57:     const Graph& graph;
alpar@209: 
deba@57:   };
deba@57: 
deba@57: }
deba@57: 
deba@57: #endif