deba@1703: /* -*- C++ -*- deba@1703: * alpar@1956: * This file is a part of LEMON, a generic C++ optimization library alpar@1956: * alpar@1956: * Copyright (C) 2003-2006 alpar@1956: * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport alpar@1956: * (Egervary Research Group on Combinatorial Optimization, EGRES). deba@1703: * deba@1703: * Permission to use, modify and distribute this software is granted deba@1703: * provided that this copyright notice appears in all copies. For deba@1703: * precise terms see the accompanying LICENSE file. deba@1703: * deba@1703: * This software is provided "AS IS" with no warranty of any kind, deba@1703: * express or implied, and with no claim as to its suitability for any deba@1703: * purpose. deba@1703: * deba@1703: */ deba@1703: deba@1703: #ifndef LEMON_STATIC_MAP_H deba@1703: #define LEMON_STATIC_MAP_H deba@1703: deba@1703: #include deba@1703: #include deba@1703: deba@1993: #include deba@1810: #include deba@1703: #include deba@1703: #include deba@1703: #include deba@1703: #include deba@1703: alpar@1946: /// \ingroup graphmaps deba@1703: /// deba@1703: ///\file deba@1703: ///\brief Static sized graph maps. deba@1703: deba@1703: namespace lemon { deba@1703: alpar@1946: /// \ingroup graphmaps deba@1703: /// deba@1703: /// \brief Graph map with static sized storage. deba@1703: /// deba@1703: /// The StaticMap template class is graph map structure what deba@1910: /// does not indate automatically the map when a key is added to or deba@1703: /// erased from the map rather it throws an exception. This map factory deba@1703: /// uses the allocators to implement the container functionality. deba@1703: /// deba@1703: /// \param Registry The AlterationNotifier that will notify this map. deba@1703: /// \param Item The item type of the graph items. deba@1703: /// \param Value The value type of the map. deba@1703: /// deba@1703: /// \author Balazs Dezso deba@1703: deba@1703: deba@1703: template deba@1703: class StaticMap : public AlterationNotifier<_Item>::ObserverBase { deba@1703: public: deba@1703: deba@1979: /// \brief Exception class for unsupported exceptions. deba@1979: class UnsupportedOperation : public lemon::LogicError { deba@1703: public: deba@1703: virtual const char* exceptionName() const { deba@1979: return "lemon::StaticMap::UnsupportedOperation"; deba@1703: } deba@1703: }; deba@1703: deba@1719: private: deba@1703: deba@1719: typedef std::vector<_Value> Container; deba@1719: deba@1719: public: deba@1719: deba@1703: /// The graph type of the map. deba@1703: typedef _Graph Graph; deba@1719: /// The reference map tag. deba@1719: typedef True ReferenceMapTag; deba@1719: deba@1703: /// The key type of the map. deba@1703: typedef _Item Key; deba@1703: /// The value type of the map. deba@1703: typedef _Value Value; deba@1719: /// The const reference type of the map. deba@1719: typedef typename Container::const_reference ConstReference; deba@1719: /// The reference type of the map. deba@1719: typedef typename Container::reference Reference; deba@1719: deba@1719: typedef const Value ConstValue; deba@1719: typedef Value* Pointer; deba@1719: typedef const Value* ConstPointer; deba@1719: deba@1719: typedef AlterationNotifier<_Item> Registry; deba@1703: deba@1703: /// The map type. deba@1703: typedef StaticMap Map; deba@1703: /// The base class of the map. deba@1703: typedef typename Registry::ObserverBase Parent; deba@1703: deba@1703: /// \brief Constructor to attach the new map into the registry. deba@1703: /// deba@1703: /// It constructs a map and attachs it into the registry. deba@1703: /// It adds all the items of the graph to the map. deba@1703: StaticMap(const Graph& _g) : graph(&_g) { deba@1703: attach(_g.getNotifier(_Item())); deba@1703: build(); deba@1703: } deba@1703: deba@1703: /// \brief Constructor uses given value to initialize the map. deba@1703: /// deba@1703: /// It constructs a map uses a given value to initialize the map. deba@1703: /// It adds all the items of the graph to the map. deba@1703: StaticMap(const Graph& _g, const Value& _v) : graph(&_g) { deba@1703: attach(_g.getNotifier(_Item())); deba@1703: unsigned size = graph->maxId(_Item()) + 1; deba@1703: container.reserve(size); deba@1703: container.resize(size, _v); deba@1703: } deba@1703: deba@1703: /// \brief Copy constructor deba@1703: /// deba@1703: /// Copy constructor. deba@1703: StaticMap(const StaticMap& _copy) : Parent(), graph(_copy.getGraph()) { deba@1703: if (_copy.attached()) { deba@1703: attach(*_copy.getRegistry()); deba@1703: container = _copy.container; deba@1703: } deba@1703: } deba@1703: deba@1703: /// \brief Destrcutor deba@1703: /// deba@1703: /// Destructor. deba@1703: virtual ~StaticMap() { deba@1703: clear(); deba@1703: if (attached()) { deba@1703: detach(); deba@1703: } deba@1703: } deba@1703: deba@1703: deba@1703: private: deba@1703: deba@1703: StaticMap& operator=(const StaticMap&); deba@1703: deba@1703: protected: deba@1703: deba@1703: using Parent::attach; deba@1703: using Parent::detach; deba@1703: using Parent::attached; deba@1703: deba@1703: const Graph* getGraph() const { deba@1703: return graph; deba@1703: } deba@1703: deba@1703: public: deba@1703: deba@1703: /// \brief The subcript operator. deba@1703: /// deba@1703: /// The subscript operator. The map can be subscripted by the deba@1703: /// actual items of the graph. deba@1703: deba@1703: Reference operator[](const Key& key) { deba@1703: return container[graph->id(key)]; deba@1703: } deba@1703: deba@1703: /// \brief The const subcript operator. deba@1703: /// deba@1703: /// The const subscript operator. The map can be subscripted by the deba@1703: /// actual items of the graph. deba@1703: deba@1703: ConstReference operator[](const Key& key) const { deba@1703: return container[graph->id(key)]; deba@1703: } deba@1703: deba@1703: deba@1703: /// \brief The setter function of the map. deba@1703: /// deba@1703: /// It the same as operator[](key) = value expression. deba@1703: /// deba@1703: void set(const Key& key, const Value& value) { deba@1703: (*this)[key] = value; deba@1703: } deba@1703: deba@1703: protected: deba@1703: deba@1703: /// \brief Adds a new key to the map. deba@1703: /// deba@1703: /// It adds a new key to the map. It called by the observer registry deba@1703: /// and it overrides the add() member function of the observer base. deba@1703: deba@1703: void add(const Key&) { deba@1979: throw UnsupportedOperation(); deba@1703: } deba@1703: deba@1703: /// \brief Erases a key from the map. deba@1703: /// deba@1703: /// Erase a key from the map. It called by the observer registry deba@1703: /// and it overrides the erase() member function of the observer base. deba@1703: void erase(const Key&) { deba@1979: throw UnsupportedOperation(); deba@1703: } deba@1703: deba@1703: /// Buildes the map. deba@1703: deba@1703: /// It buildes the map. It called by the observer registry deba@1703: /// and it overrides the build() member function of the observer base. deba@1703: deba@1703: void build() { deba@1703: int size = graph->maxId(_Item()) + 1; deba@1703: container.reserve(size); deba@1703: container.resize(size); deba@1703: } deba@1703: deba@1703: /// Clear the map. deba@1703: deba@1703: /// It erase all items from the map. It called by the observer registry deba@1703: /// and it overrides the clear() member function of the observer base. deba@1703: void clear() { deba@1703: container.clear(); deba@1703: } deba@1703: deba@1703: private: deba@1703: deba@1703: Container container; deba@1703: const Graph *graph; deba@1703: deba@1703: }; deba@1703: deba@1703: } deba@1703: deba@1703: #endif