[Lemon-commits] [lemon_svn] deba: r1888 - in hugo/trunk: doc src/lemon

Lemon SVN svn at lemon.cs.elte.hu
Mon Nov 6 20:48:28 CET 2006


Author: deba
Date: Sat May 14 19:32:11 2005
New Revision: 1888

Added:
   hugo/trunk/doc/adaptor_references.dox
Modified:
   hugo/trunk/src/lemon/utility.h

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



Added: hugo/trunk/doc/adaptor_references.dox
==============================================================================
--- (empty file)
+++ hugo/trunk/doc/adaptor_references.dox	Sat May 14 19:32:11 2005
@@ -0,0 +1,170 @@
+namespace lemon {
+/*!
+
+\page adaptor-references Smart Reference Handling
+
+The adaptor classes are very useful tools in the lemon library. It makes
+possible to create various data view of the current data structures without
+of the copy of them. This makes the lemon programming efficient and 
+consederably fast.
+
+\section problem The problem
+
+The adaptors usually use references or pointers to reference to an 
+existing data structure. We may use an algorithm in the next way:
+\code
+function_algorithm(adaptor(structure));
+\endcode 
+
+But what about the class algorithms:
+\code
+class_algorithm alg;
+alg.add(adaptor(structure));
+alg.run();
+\endcode
+The algorithm store a reference to the given structure. It is a created
+as temporarly and when the expression of the \c add() function is evaluated it
+will be destructed. It is very dangerous handling of the adaptors.
+
+\section solution The solution
+
+We made reference to a temporarly constructed adaptor but we should make
+a copy of the adaptor when it is given as parameter to a class.
+It is not impossible with a little tranformation of the code.
+
+Let's first create some helper class:
+\code
+template <typename _Type, typename Enable = void>
+struct SmartConstReference {
+  typedef const _Type& Type;
+};
+  
+template <typename _Type>
+struct SmartConstReference<
+  _Type, 
+  typename enable_if<typename _Type::NeedCopy, void>::type
+> {
+  typedef const _Type Type;
+};
+\endcode
+Then we can place NeedCopy tags in the adaptor classes:
+\code
+template<class M1,class M2> 
+class AddMap {
+  typename SmartConstReference<M1>::Type m1;
+  typename SmartConstReference<M2>::Type m2;
+
+public:
+
+  typedef True NeedCopy;
+
+  typedef typename M1::Key Key;
+  typedef typename M1::Value Value;
+
+  AddMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
+  Value operator[](Key k) const {return m1[k]+m2[k];}
+};
+\endcode
+Then we can transform all of the template map and graph references to
+\c SmartConstReference<Map>::Type or \c SmartConstReference<Graph>::Type.
+This way we copy all of maps and graphs what we should copy but the
+greater data structures are not copied.
+
+\section not-const If the adaptor is not const
+The solution is very similar but it gives an additional problem.
+We make the same \c SmartReferences:
+\code
+template <typename _Type, typename Enable = void>
+struct SmartReference {
+  typedef _Type& Type;
+};
+
+template <typename _Type>
+struct SmartReference<
+  _Type, 
+  typename enable_if<typename _Type::NeedCopy, void>::type
+> {
+  typedef _Type Type;
+};
+\endcode
+Let's create a class that use it:
+\code
+template <typename Map>
+class Algorithm {
+public:
+  SmartReference<Map>::Type map;
+  Algorithm(Map& _map) : map(_map) {}
+  ...
+};
+\endcode
+But if we want to give an adaptor function as parameter
+it will be a compile error. The adaptor will be created as temporarly
+so it cannot give as reference just as const reference.
+
+Make more helper class:
+\code
+template <typename _Type, typename Enable = void>
+struct SmartParameter {
+  typedef _Type& Type;
+};
+
+template <typename _Type>
+struct SmartParameter<
+  _Type, 
+  typename enable_if<typename _Type::NeedCopy, void>::type
+> {
+  typedef const _Type& Type;
+};
+\endcode
+And the repaired code:
+\code
+template <typename Map>
+class Algorithm {
+public:
+  SmartReference<Map>::Type map;
+  Algorithm(SmartParameter<Map>::Type _map) : map(_map) {}
+  ...
+};
+\endcode
+But some times it does not help:
+\code
+class Algorithm {
+public:
+  ...
+
+  template <typename Map>
+  void addMap(SmartParameter<Map>::Type _map) {
+    ...
+  }
+  ...
+};
+\endcode
+Actually, it is a good code but the template parameter should
+be written because it cannot be found out from the parameter type.
+This can be solved with a bigger transformation:
+\code
+class Algorithm {
+public:
+  ...
+
+  template <typename Map>
+  void addMap(const Map& _map) {
+    _addMap<SmartParameter<Map>::Type, Map>(_map);
+  }
+  template <typename Map>
+  void addMap(const Map& _map) {
+    _addMap<SmartParameter<Map>::Type, Map>(_map);
+  }
+
+private:
+  template <typename MapParameter, typename Map>
+  void _addMap(MapParameter _map) {
+    ...
+  }
+  ...
+};
+\endcode
+This way we solved the smart referencing problem.
+\author Balazs Dezso
+*/
+}

Modified: hugo/trunk/src/lemon/utility.h
==============================================================================
--- hugo/trunk/src/lemon/utility.h	(original)
+++ hugo/trunk/src/lemon/utility.h	Sat May 14 19:32:11 2005
@@ -107,6 +107,47 @@
   template <class Cond, class T> 
   struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {};
 
+  // smart referencing
+
+  template <typename _Type, typename Enable = void>
+  struct SmartReference {
+    typedef _Type& Type;
+  };
+  
+  template <typename _Type>
+  struct SmartReference<
+    _Type, 
+    typename enable_if<typename _Type::NeedCopy, void>::type
+  > {
+    typedef _Type Type;
+  };
+
+  template <typename _Type, typename Enable = void>
+  struct SmartConstReference {
+    typedef const _Type& Type;
+  };
+  
+  template <typename _Type>
+  struct SmartConstReference<
+    _Type, 
+    typename enable_if<typename _Type::NeedCopy, void>::type
+  > {
+    typedef const _Type Type;
+  };
+
+  template <typename _Type, typename Enable = void>
+  struct SmartParameter {
+    typedef _Type& Type;
+  };
+  
+  template <typename _Type>
+  struct SmartParameter<
+    _Type, 
+    typename enable_if<typename _Type::NeedCopy, void>::type
+  > {
+    typedef const _Type& Type;
+  };
+
 } // namespace lemon
 
 #endif



More information about the Lemon-commits mailing list