COIN-OR::LEMON - Graph Library

source: lemon-0.x/doc/adaptor_references.dox @ 1418:afaa773d0ad0

Last change on this file since 1418:afaa773d0ad0 was 1418:afaa773d0ad0, checked in by Balazs Dezso, 19 years ago

Handling smarter the references
It's used by the lemon IO and proposed by the adaptors.

File size: 4.1 KB
Line 
1namespace lemon {
2/*!
3
4\page adaptor-references Smart Reference Handling
5
6The adaptor classes are very useful tools in the lemon library. It makes
7possible to create various data view of the current data structures without
8of the copy of them. This makes the lemon programming efficient and
9consederably fast.
10
11\section problem The problem
12
13The adaptors usually use references or pointers to reference to an
14existing data structure. We may use an algorithm in the next way:
15\code
16function_algorithm(adaptor(structure));
17\endcode
18
19But what about the class algorithms:
20\code
21class_algorithm alg;
22alg.add(adaptor(structure));
23alg.run();
24\endcode
25The algorithm store a reference to the given structure. It is a created
26as temporarly and when the expression of the \c add() function is evaluated it
27will be destructed. It is very dangerous handling of the adaptors.
28
29\section solution The solution
30
31We made reference to a temporarly constructed adaptor but we should make
32a copy of the adaptor when it is given as parameter to a class.
33It is not impossible with a little tranformation of the code.
34
35Let's first create some helper class:
36\code
37template <typename _Type, typename Enable = void>
38struct SmartConstReference {
39  typedef const _Type& Type;
40};
41 
42template <typename _Type>
43struct SmartConstReference<
44  _Type,
45  typename enable_if<typename _Type::NeedCopy, void>::type
46> {
47  typedef const _Type Type;
48};
49\endcode
50Then we can place NeedCopy tags in the adaptor classes:
51\code
52template<class M1,class M2>
53class AddMap {
54  typename SmartConstReference<M1>::Type m1;
55  typename SmartConstReference<M2>::Type m2;
56
57public:
58
59  typedef True NeedCopy;
60
61  typedef typename M1::Key Key;
62  typedef typename M1::Value Value;
63
64  AddMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
65  Value operator[](Key k) const {return m1[k]+m2[k];}
66};
67\endcode
68Then we can transform all of the template map and graph references to
69\c SmartConstReference<Map>::Type or \c SmartConstReference<Graph>::Type.
70This way we copy all of maps and graphs what we should copy but the
71greater data structures are not copied.
72
73\section not-const If the adaptor is not const
74The solution is very similar but it gives an additional problem.
75We make the same \c SmartReferences:
76\code
77template <typename _Type, typename Enable = void>
78struct SmartReference {
79  typedef _Type& Type;
80};
81
82template <typename _Type>
83struct SmartReference<
84  _Type,
85  typename enable_if<typename _Type::NeedCopy, void>::type
86> {
87  typedef _Type Type;
88};
89\endcode
90Let's create a class that use it:
91\code
92template <typename Map>
93class Algorithm {
94public:
95  SmartReference<Map>::Type map;
96  Algorithm(Map& _map) : map(_map) {}
97  ...
98};
99\endcode
100But if we want to give an adaptor function as parameter
101it will be a compile error. The adaptor will be created as temporarly
102so it cannot give as reference just as const reference.
103
104Make more helper class:
105\code
106template <typename _Type, typename Enable = void>
107struct SmartParameter {
108  typedef _Type& Type;
109};
110
111template <typename _Type>
112struct SmartParameter<
113  _Type,
114  typename enable_if<typename _Type::NeedCopy, void>::type
115> {
116  typedef const _Type& Type;
117};
118\endcode
119And the repaired code:
120\code
121template <typename Map>
122class Algorithm {
123public:
124  SmartReference<Map>::Type map;
125  Algorithm(SmartParameter<Map>::Type _map) : map(_map) {}
126  ...
127};
128\endcode
129But some times it does not help:
130\code
131class Algorithm {
132public:
133  ...
134
135  template <typename Map>
136  void addMap(SmartParameter<Map>::Type _map) {
137    ...
138  }
139  ...
140};
141\endcode
142Actually, it is a good code but the template parameter should
143be written because it cannot be found out from the parameter type.
144This can be solved with a bigger transformation:
145\code
146class Algorithm {
147public:
148  ...
149
150  template <typename Map>
151  void addMap(const Map& _map) {
152    _addMap<SmartParameter<Map>::Type, Map>(_map);
153  }
154  template <typename Map>
155  void addMap(const Map& _map) {
156    _addMap<SmartParameter<Map>::Type, Map>(_map);
157  }
158
159private:
160  template <typename MapParameter, typename Map>
161  void _addMap(MapParameter _map) {
162    ...
163  }
164  ...
165};
166\endcode
167This way we solved the smart referencing problem.
168\author Balazs Dezso
169*/
170}
Note: See TracBrowser for help on using the repository browser.