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