Little modifications
authordeba
Thu, 06 Oct 2005 09:58:21 +0000
changeset 17124fb435ad31cf
parent 1711 1d09b48e8d55
child 1713 49d22d34d95f
Little modifications
doc/adaptor_references.dox
lemon/graph_utils.h
test/graph_test.cc
     1.1 --- a/doc/adaptor_references.dox	Thu Oct 06 09:57:23 2005 +0000
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,170 +0,0 @@
     1.4 -namespace lemon {
     1.5 -/*!
     1.6 -
     1.7 -\page adaptor-references Smart Reference Handling
     1.8 -
     1.9 -The adaptor classes are very useful tools in the lemon library. It makes
    1.10 -possible to create various data view of the current data structures without
    1.11 -of the copy of them. This makes the lemon programming efficient and 
    1.12 -consederably fast.
    1.13 -
    1.14 -\section problem The problem
    1.15 -
    1.16 -The adaptors usually use references or pointers to reference to an 
    1.17 -existing data structure. We may use an algorithm in the following way:
    1.18 -\code
    1.19 -function_algorithm(adaptor(structure));
    1.20 -\endcode 
    1.21 -
    1.22 -But what about the class algorithms:
    1.23 -\code
    1.24 -class_algorithm alg;
    1.25 -alg.add(adaptor(structure));
    1.26 -alg.run();
    1.27 -\endcode
    1.28 -The algorithm store a reference to the given structure. It is a created
    1.29 -as temporarly and when the expression of the \c add() function is evaluated it
    1.30 -will be destructed. It is very dangerous handling of the adaptors.
    1.31 -
    1.32 -\section solution The solution
    1.33 -
    1.34 -We made reference to a temporarly constructed adaptor but we should make
    1.35 -a copy of the adaptor when it is given as parameter to a class.
    1.36 -It is not impossible with a little tranformation of the code.
    1.37 -
    1.38 -Let's first create some helper class:
    1.39 -\code
    1.40 -template <typename _Type, typename Enable = void>
    1.41 -struct SmartConstReference {
    1.42 -  typedef const _Type& Type;
    1.43 -};
    1.44 -  
    1.45 -template <typename _Type>
    1.46 -struct SmartConstReference<
    1.47 -  _Type, 
    1.48 -  typename enable_if<typename _Type::NeedCopy, void>::type
    1.49 -> {
    1.50 -  typedef const _Type Type;
    1.51 -};
    1.52 -\endcode
    1.53 -Then we can place NeedCopy tags in the adaptor classes:
    1.54 -\code
    1.55 -template<class M1,class M2> 
    1.56 -class AddMap {
    1.57 -  typename SmartConstReference<M1>::Type m1;
    1.58 -  typename SmartConstReference<M2>::Type m2;
    1.59 -
    1.60 -public:
    1.61 -
    1.62 -  typedef True NeedCopy;
    1.63 -
    1.64 -  typedef typename M1::Key Key;
    1.65 -  typedef typename M1::Value Value;
    1.66 -
    1.67 -  AddMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
    1.68 -  Value operator[](Key k) const {return m1[k]+m2[k];}
    1.69 -};
    1.70 -\endcode
    1.71 -Then we can transform all of the template map and graph references to
    1.72 -\c SmartConstReference<Map>::Type or \c SmartConstReference<Graph>::Type.
    1.73 -This way we copy all of maps and graphs what we should copy but the
    1.74 -greater data structures are not copied.
    1.75 -
    1.76 -\section not-const If the adaptor is not const
    1.77 -The solution is very similar but it gives an additional problem.
    1.78 -We make the same \c SmartReferences:
    1.79 -\code
    1.80 -template <typename _Type, typename Enable = void>
    1.81 -struct SmartReference {
    1.82 -  typedef _Type& Type;
    1.83 -};
    1.84 -
    1.85 -template <typename _Type>
    1.86 -struct SmartReference<
    1.87 -  _Type, 
    1.88 -  typename enable_if<typename _Type::NeedCopy, void>::type
    1.89 -> {
    1.90 -  typedef _Type Type;
    1.91 -};
    1.92 -\endcode
    1.93 -Let's create a class that use it:
    1.94 -\code
    1.95 -template <typename Map>
    1.96 -class Algorithm {
    1.97 -public:
    1.98 -  SmartReference<Map>::Type map;
    1.99 -  Algorithm(Map& _map) : map(_map) {}
   1.100 -  ...
   1.101 -};
   1.102 -\endcode
   1.103 -But if we want to give an adaptor function as parameter
   1.104 -it will be a compile error. The adaptor will be created as temporarly
   1.105 -so it cannot give as reference just as const reference.
   1.106 -
   1.107 -Make more helper class:
   1.108 -\code
   1.109 -template <typename _Type, typename Enable = void>
   1.110 -struct SmartParameter {
   1.111 -  typedef _Type& Type;
   1.112 -};
   1.113 -
   1.114 -template <typename _Type>
   1.115 -struct SmartParameter<
   1.116 -  _Type, 
   1.117 -  typename enable_if<typename _Type::NeedCopy, void>::type
   1.118 -> {
   1.119 -  typedef const _Type& Type;
   1.120 -};
   1.121 -\endcode
   1.122 -And the repaired code:
   1.123 -\code
   1.124 -template <typename Map>
   1.125 -class Algorithm {
   1.126 -public:
   1.127 -  SmartReference<Map>::Type map;
   1.128 -  Algorithm(SmartParameter<Map>::Type _map) : map(_map) {}
   1.129 -  ...
   1.130 -};
   1.131 -\endcode
   1.132 -But some times it does not help:
   1.133 -\code
   1.134 -class Algorithm {
   1.135 -public:
   1.136 -  ...
   1.137 -
   1.138 -  template <typename Map>
   1.139 -  void addMap(SmartParameter<Map>::Type _map) {
   1.140 -    ...
   1.141 -  }
   1.142 -  ...
   1.143 -};
   1.144 -\endcode
   1.145 -Actually, it is a good code but the template parameter should
   1.146 -be written because it cannot be found out from the parameter type.
   1.147 -This can be solved with a bigger transformation:
   1.148 -\code
   1.149 -class Algorithm {
   1.150 -public:
   1.151 -  ...
   1.152 -
   1.153 -  template <typename Map>
   1.154 -  void addMap(const Map& _map) {
   1.155 -    _addMap<SmartParameter<Map>::Type, Map>(_map);
   1.156 -  }
   1.157 -  template <typename Map>
   1.158 -  void addMap(const Map& _map) {
   1.159 -    _addMap<SmartParameter<Map>::Type, Map>(_map);
   1.160 -  }
   1.161 -
   1.162 -private:
   1.163 -  template <typename MapParameter, typename Map>
   1.164 -  void _addMap(MapParameter _map) {
   1.165 -    ...
   1.166 -  }
   1.167 -  ...
   1.168 -};
   1.169 -\endcode
   1.170 -This way we solved the smart referencing problem.
   1.171 -\author Balazs Dezso
   1.172 -*/
   1.173 -}
     2.1 --- a/lemon/graph_utils.h	Thu Oct 06 09:57:23 2005 +0000
     2.2 +++ b/lemon/graph_utils.h	Thu Oct 06 09:58:21 2005 +0000
     2.3 @@ -1400,7 +1400,7 @@
     2.4      }
     2.5  
     2.6      void add(const Node& node) {
     2.7 -      if (size(graph.id(node) + 1) > values.size()) {
     2.8 +      if (size(graph.id(node) + 1) >= (int)values.size()) {
     2.9  	values.resize(size(graph.id(node) + 1));	
    2.10        }
    2.11      }
     3.1 --- a/test/graph_test.cc	Thu Oct 06 09:57:23 2005 +0000
     3.2 +++ b/test/graph_test.cc	Thu Oct 06 09:58:21 2005 +0000
     3.3 @@ -7,6 +7,7 @@
     3.4  #include <lemon/list_graph.h>
     3.5  #include <lemon/smart_graph.h>
     3.6  #include <lemon/full_graph.h>
     3.7 +#include <lemon/hypercube_graph.h>
     3.8  
     3.9  #include "test_tools.h"
    3.10  #include "graph_test.h"
    3.11 @@ -59,6 +60,9 @@
    3.12    { // checking full graph
    3.13      checkConcept<StaticGraph, FullGraph >();
    3.14    }
    3.15 +  { // checking full graph
    3.16 +    checkConcept<StaticGraph, HyperCubeGraph >();
    3.17 +  }
    3.18  
    3.19    std::cout << __FILE__ ": All tests passed.\n";
    3.20