[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