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 following 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 struct SmartConstReference { typedef const _Type& Type; }; template struct SmartConstReference< _Type, typename enable_if::type > { typedef const _Type Type; }; \endcode Then we can place NeedCopy tags in the adaptor classes: \code template class AddMap { typename SmartConstReference::Type m1; typename SmartConstReference::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::Type or \c SmartConstReference::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 struct SmartReference { typedef _Type& Type; }; template struct SmartReference< _Type, typename enable_if::type > { typedef _Type Type; }; \endcode Let's create a class that use it: \code template class Algorithm { public: SmartReference::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 struct SmartParameter { typedef _Type& Type; }; template struct SmartParameter< _Type, typename enable_if::type > { typedef const _Type& Type; }; \endcode And the repaired code: \code template class Algorithm { public: SmartReference::Type map; Algorithm(SmartParameter::Type _map) : map(_map) {} ... }; \endcode But some times it does not help: \code class Algorithm { public: ... template void addMap(SmartParameter::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 void addMap(const Map& _map) { _addMap::Type, Map>(_map); } template void addMap(const Map& _map) { _addMap::Type, Map>(_map); } private: template void _addMap(MapParameter _map) { ... } ... }; \endcode This way we solved the smart referencing problem. \author Balazs Dezso */ }