Salome HOME
Revert "Synchronize adm files"
[modules/kernel.git] / src / DSC / DSC_User / Datastream / Calcium / CalciumCouplingPolicy.hxx
1 // Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  File   : CalciumCouplingPolicy.hxx
24 //  Author : Eric Fayolle (EDF)
25 //  Module : KERNEL
26 // Id          : $Id$
27 //
28 #ifndef __CALCIUM_COUPLING_POLICY__ 
29 #define __CALCIUM_COUPLING_POLICY__
30
31 #include <vector>
32 #include <map>
33
34 #include "DisplayPair.hxx"
35 #include "CouplingPolicy.hxx"
36 #include "AdjacentFunctor.hxx"
37 #include <boost/lambda/lambda.hpp>
38 #include <boost/utility/enable_if.hpp>
39 #include <boost/type_traits/is_arithmetic.hpp>
40 #include "CalciumTypes.hxx"
41 #include "CalciumException.hxx"
42
43 //#define MYDEBUG
44
45 class CalciumCouplingPolicy : public CouplingPolicy  {
46
47
48 public:
49
50   template <typename T_TIME, typename T_TAG >        class InternalDataIdContainer;
51   template <typename T_TIME, typename T_TAG > friend class InternalDataIdContainer;
52   template <typename DataManipulator, 
53     class EnableIf >                  friend class BoundedDataIdProcessor;
54   template <typename DataManipulator >        friend class EraseDataIdProcessor;
55   template <typename DataManipulator >        friend class EraseDataIdBeforeOrAfterTagProcessor;
56   template <typename DataManipulator >        friend class DisconnectProcessor;
57
58   typedef CalciumTypes::DependencyType       DependencyType;
59   typedef CalciumTypes::DateCalSchem         DateCalSchem;
60   typedef CalciumTypes::InterpolationSchem   InterpolationSchem;
61   typedef CalciumTypes::ExtrapolationSchem   ExtrapolationSchem;
62   typedef CalciumTypes::DisconnectDirective  DisconnectDirective;  
63
64 private:
65
66   DependencyType      _dependencyType;
67   size_t              _storageLevel;
68   DateCalSchem        _dateCalSchem;
69   InterpolationSchem  _interpolationSchem;
70   ExtrapolationSchem  _extrapolationSchem;
71   double              _alpha;
72   double              _deltaT;
73   DisconnectDirective _disconnectDirective;
74
75 public:
76   CalciumCouplingPolicy();
77
78   void           setDependencyType (DependencyType dependencyType);
79   DependencyType getDependencyType () const;
80  
81   void   setStorageLevel   (size_t storageLevel);
82   size_t getStorageLevel   () const;
83
84   void         setDateCalSchem   (DateCalSchem   dateCalSchem);
85   DateCalSchem getDateCalSchem () const;
86
87   void   setAlpha(double alpha);
88   double getAlpha() const ;
89
90   void   setDeltaT(double deltaT );
91   double getDeltaT() const ;
92
93   void setInterpolationSchem (InterpolationSchem interpolationSchem);
94   void setExtrapolationSchem (ExtrapolationSchem extrapolationSchem);
95   InterpolationSchem getInterpolationSchem () const ;
96   ExtrapolationSchem getExtrapolationSchem () const ;
97
98   // Classe DataId rassemblant les paramètres de la méthode PORT::put 
99   // qui identifient l'instance d'une donnée pour Calcium
100   // Rem : Le DataId doit pouvoir être une key dans une map stl
101   typedef double TimeType;
102   typedef long   TagType;
103   typedef std::pair< TimeType , TagType >     DataId;
104   typedef InternalDataIdContainer < TimeType , TagType >  DataIdContainer;
105   typedef std::vector< DataId >::iterator  iterator;
106
107   template <typename T_TIME, typename T_TAG >  
108   struct InternalDataIdContainer;
109
110   inline TimeType getTime(const DataId &dataId) const { return dataId.first;}
111   inline TagType  getTag (const DataId &dataId) const { return dataId.second;}
112
113   template <typename DataManipulator, 
114             class EnableIf = void >    struct BoundedDataIdProcessor;
115   //template <typename DataManipulator>  struct BoundedDataIdProcessor;
116   template <typename DataManipulator>  struct EraseDataIdProcessor;
117   template <typename DataManipulator>  struct EraseDataIdBeforeOrAfterTagProcessor;
118   template <typename DataManipulator>  struct DisconnectProcessor;
119
120   // Renvoie isEqual si le dataId attendu est trouvé dans storedDataIds :
121   //   - l'itérateur wDataIt1 pointe alors sur ce dataId
122   // Renvoie isBounded si le dataId attendu n'est pas trouvé mais encadrable et 
123   // que la politique de couplage gére ce cas de figure 
124   //   - l'itérateur wDataIt1 est tel que wDataIt1->first < wdataId < (wDataIt1+1)->first
125   // Le container doit être associatif
126   template < typename AssocContainer >
127   bool isDataIdConveniant( AssocContainer & storedDatas, 
128                            const typename AssocContainer::key_type & expectedDataId,
129                            bool & isEqual, bool & isBounded, 
130                            typename AssocContainer::iterator & wDataIt1) const;
131
132   TimeType getEffectiveTime(TimeType ti, TimeType tf);
133
134   void disconnect(bool provideLastGivenValue);
135
136 }; //Fin de CalciumCouplingPolicy
137
138
139
140 //*************   DEFINITION DES METHODES ET OBJETS TEMPLATES *************// 
141
142
143
144 // Définition du container de DataId pour répondre au concept
145 // de mode de couplage
146 template <typename T_TIME, typename T_TAG > 
147 struct CalciumCouplingPolicy::InternalDataIdContainer : public std::vector< std::pair< T_TIME,T_TAG> >  {
148   typedef std::vector < DataId >        DataIdVect;
149     
150   InternalDataIdContainer(const DataId & dataId, 
151                           const CalciumCouplingPolicy & policy
152                           ):std::vector< std::pair< T_TIME,T_TAG> >() {
153     // Ignore les paramètres qui ne sont pas en rapport avec le type de dépendance
154     switch (policy._dependencyType) {
155     case CalciumTypes::TIME_DEPENDENCY:
156       this->push_back(DataId(dataId.first,0));
157       break;
158     case CalciumTypes::ITERATION_DEPENDENCY:
159       this->push_back(DataId(0,dataId.second));
160       break;
161     default:
162       throw(CalciumException(CalciumTypes::CPIT,LOC("The dependency type must be set by setDependencyType before calling DataIdContainer contructor")));
163       break;
164     }
165   };
166 };
167
168
169 template <typename DataManipulator, class EnableIf >
170 struct CalciumCouplingPolicy::BoundedDataIdProcessor{
171   BoundedDataIdProcessor(const CouplingPolicy & couplingPolicy) {};
172   template < typename Iterator, typename DataId > 
173   void inline apply(typename iterator_t<Iterator>::value_type & data,
174                     const DataId & dataId,
175                     const Iterator  & it1) const {
176     typedef typename iterator_t<Iterator>::value_type value_type;
177 #ifdef MYDEBUG
178     std::cout << "-------- Calcium Generic BoundedDataIdProcessor.apply() called " << std::endl;
179 #endif
180
181   }
182 };
183
184
185 template <typename DataManipulator >
186 struct CalciumCouplingPolicy::BoundedDataIdProcessor<
187   DataManipulator, 
188   typename boost::enable_if< boost::is_float< typename DataManipulator::InnerType> >::type > {
189     
190   const CalciumCouplingPolicy & _couplingPolicy;
191     
192   BoundedDataIdProcessor(const CalciumCouplingPolicy &couplingPolicy):
193     _couplingPolicy(couplingPolicy) {};
194     
195   // Méthode implémentant l'interpolation temporelle
196   template < typename MapIterator > 
197   void inline apply (typename iterator_t<MapIterator>::value_type & data,
198                      const DataId & dataId, const MapIterator & it1) const {
199       
200     typedef typename iterator_t<MapIterator>::value_type value_type;
201     typedef typename DataManipulator::InnerType InnerType;
202     typedef typename DataManipulator::Type Type;
203
204     MapIterator it2=it1; ++it2;
205     size_t   dataSize1 = DataManipulator::size(it1->second);
206 #ifdef MYDEBUG
207     std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Taille de donnée dataId1 : " << dataSize1 << std::endl;
208 #endif
209  
210     // Gérer dans calcium la limite de la taille du buffer donnée par
211     // l'utilisateur.
212     size_t   dataSize2 = DataManipulator::size(it2->second);
213 #ifdef MYDEBUG
214     std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Taille de donnée dataId2 : " << dataSize2 << std::endl;
215 #endif
216
217     size_t   dataSize  = std::min< size_t >( dataSize1, dataSize2 );
218     DataId   dataId2 = it2->first;
219     DataId   dataId1 = it1->first;
220     TimeType t2      = dataId2.first;
221     TimeType t1      = dataId1.first;
222 #ifdef MYDEBUG
223     std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Valeur de t1 : " << t1 << std::endl;
224     std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Valeur de t2 : " << t2 << std::endl;
225 #endif
226     TimeType t       = dataId.first;
227 #ifdef MYDEBUG
228     std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Valeur de t : " << t << std::endl;
229 #endif
230     TimeType timeDiff  = t2-t1;
231 #ifdef MYDEBUG
232     std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Valeur de timeDiff : " << timeDiff << std::endl;
233 #endif
234     TimeType coeff   = (t2-t)/timeDiff;
235 #ifdef MYDEBUG
236     std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Valeur de coeff : " << coeff << std::endl;
237 #endif
238
239     InnerType const * const InIt1 = DataManipulator::getPointer(it1->second);
240 #ifdef MYDEBUG
241     std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Données à t1 : " << std::endl;
242     std::copy(InIt1,InIt1+dataSize1,std::ostream_iterator<InnerType>(std::cout," "));
243     std::cout << std::endl;
244 #endif
245     InnerType const * const InIt2 = DataManipulator::getPointer(it2->second);
246 #ifdef MYDEBUG
247     std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Données à t2 : " << std::endl;
248     std::copy(InIt2,InIt2+dataSize2,std::ostream_iterator<InnerType>(std::cout," "));
249     std::cout << std::endl;
250 #endif
251     Type              dataOut = DataManipulator::create(dataSize);
252     InnerType * const OutIt   = DataManipulator::getPointer(dataOut);
253  
254 #ifdef MYDEBUG
255     std::cerr << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : interpolationSchem : " << _couplingPolicy._interpolationSchem << std::endl;
256     std::cerr << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : alpha : " << _couplingPolicy._alpha << std::endl;
257     std::cerr << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : datecalschem : " << _couplingPolicy._dateCalSchem << std::endl;
258     std::cerr << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : storageLevel : " << _couplingPolicy._storageLevel << std::endl;
259 #endif
260     if ( timeDiff == 0.0 ||  _couplingPolicy._interpolationSchem == CalciumTypes::L0_SCHEM ) {
261       std::copy(InIt1,InIt1+dataSize,OutIt);
262     } else {
263
264       boost::lambda::placeholder1_type _1;
265       boost::lambda::placeholder2_type _2;
266       // OLD: REM : Pour des buffers de type int
267       // OLD: le compilo indiquera warning: converting to `long int' from `Double'
268       std::transform(InIt1,InIt1+dataSize,InIt2,OutIt,
269                      ( _1 - _2 ) * coeff + _2 );
270 //       for(size_t i =0;  i < dataSize3; ++i) {
271 //      OutIt[i]=(InIt1[i] - InIt2[i]) * coeff + InIt2[i];
272 //       }
273
274     }
275 #ifdef MYDEBUG
276     std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Données calculées à t : " << std::endl;
277     std::copy(OutIt,OutIt+dataSize,std::ostream_iterator<InnerType>(std::cout," "));
278     std::cout << std::endl;
279 #endif
280     data = dataOut;
281     
282   }
283 };
284
285 // Renvoie isEqual si le dataId attendu est trouvé dans storedDataIds :
286 //   - l'itérateur wDataIt1 pointe alors sur ce dataId
287 // Renvoie isBounded si le dataId attendu n'est pas trouvé mais encadrable et 
288 // que la politique de couplage gére ce cas de figure 
289 //   - l'itérateur wDataIt1 est tel que wDataIt1->first < wdataId < (wDataIt1+1)->first
290 // Le container doit être associatif
291 template < typename AssocContainer >
292 bool CalciumCouplingPolicy::isDataIdConveniant( AssocContainer & storedDatas, const typename AssocContainer::key_type & expectedDataId,
293                                                 bool & isEqual, bool & isBounded, typename AssocContainer::iterator & wDataIt1) const {
294  
295   // Rem : le type key_type == DataId
296   typedef typename AssocContainer::key_type key_type;
297   AdjacentFunctor< key_type > af(expectedDataId);
298   if ( _dependencyType == CalciumTypes::TIME_DEPENDENCY )
299   {
300 #ifdef MYDEBUG
301     std::cout << "-------- time expected : " << expectedDataId.first << std::endl;
302     std::cout << "-------- time expected corrected : " << expectedDataId.first*(1.0-_deltaT) << std::endl;
303 #endif
304     af.setMaxValue(key_type(expectedDataId.first*(1.0-_deltaT),0));
305   }
306   isBounded = false;
307
308   // Rem 1 :
309   // L'algo adjacent_find ne peut être utilisé avec l'AdjacentPredicate 
310   //   - si la table contient un seul élément l'algorithme adjacent_find retourne end()
311   //     que se soit l'élément attendu ou non
312   //   - si la table contient deux éléments dont le dernier est celui recherché
313   //     l'algorithme adjacent_find retourne end() aussi
314   //   d'ou la necessité d'effectuer  un find avant ou d'écrire un algorithme ad hoc
315  
316   // Rem 2 :
317   //
318   // L'algo find_if ne peut être utilisé car il recopie l'AdjacentFunctor
319   // qui ne peut alors pas mémoriser ses états précédents
320   //    
321  
322   // Un codage en reverse serait plus efficace
323   typename AssocContainer::iterator prev    = storedDatas.begin();
324   typename AssocContainer::iterator current = prev;
325   while ( (current != storedDatas.end()) && !af(current->first)  ) 
326   {
327 #ifdef MYDEBUG
328     std::cerr << "------- stored time : " << current->first << std::endl;
329 #endif
330     //  if ( af(current->first) ) break;
331     prev = current++;
332   }
333
334   isEqual = af.isEqual();
335     
336   // On considère qu'il n'est pas possible d'encadrer en dépendance itérative,
337   // on se veut pas calculer d'interpolation. 
338   if  ( _dependencyType == CalciumTypes::TIME_DEPENDENCY)  isBounded = af.isBounded();
339
340   if ( isEqual ) wDataIt1 = current;
341   else 
342     if (isBounded) wDataIt1 = prev;
343     else
344       wDataIt1 = storedDatas.end();
345
346 #ifdef MYDEBUG
347   std::cout << "-------- isDataIdConvenient : isEqual : " << isEqual << " , isBounded " << isBounded << std::endl;
348 #endif
349
350   return isEqual || isBounded;
351 }
352
353 //Remove DataId before or after a given time or tag
354 template < typename DataManipulator > 
355 struct CalciumCouplingPolicy::EraseDataIdBeforeOrAfterTagProcessor
356 {
357   CalciumCouplingPolicy &_couplingPolicy;
358     
359   EraseDataIdBeforeOrAfterTagProcessor(CalciumCouplingPolicy &couplingPolicy):
360     _couplingPolicy(couplingPolicy) {};
361
362   template < typename Container,typename TimeType,typename TagType >
363   void apply(Container & storedDatas, TimeType time, TagType tag, bool before) const 
364     {
365       typedef typename Container::iterator   iterator;
366       typedef typename Container::reverse_iterator   riterator;
367
368       if(_couplingPolicy._dependencyType == CalciumTypes::TIME_DEPENDENCY)
369         {
370           if(before)
371             {
372               iterator it=storedDatas.begin();
373               while(it != storedDatas.end() && it->first.first <= time)
374                 {
375                   DataManipulator::delete_data(it->second);
376                   storedDatas.erase(it);
377                   it=storedDatas.begin();
378                 }
379             }
380           else
381             {
382               riterator it=storedDatas.rbegin();
383               while(it != storedDatas.rend() && it->first.first >= time)
384                 {
385                   DataManipulator::delete_data(it->second);
386                   storedDatas.erase(it->first);
387                   it=storedDatas.rbegin();
388                 }
389             }
390         }
391       else
392         {
393           if(before)
394             {
395               iterator it=storedDatas.begin();
396               while(it != storedDatas.end() && it->first.second <= tag)
397                 {
398                   DataManipulator::delete_data(it->second);
399                   storedDatas.erase(it);
400                   it=storedDatas.begin();
401                 }
402             }
403           else
404             {
405               riterator it=storedDatas.rbegin();
406               while(it != storedDatas.rend() && it->first.second >= tag)
407                 {
408                   DataManipulator::delete_data(it->second);
409                   storedDatas.erase(it->first);
410                   it=storedDatas.rbegin();
411                 }
412             }
413         }
414     }
415 };
416
417 // TODO :PAS ENCORE TESTE AVEC UN NIVEAU POSITIONNE
418 // Supprime les DataId et les données associées
419 // du container associatif quand le nombre
420 // de données stockées dépasse le niveau CALCIUM.
421 // Cette méthode est appelée de GenericPort::get et GenericPort::next 
422 // TODO : Elle devrait également être appelée dans GenericPort::Put
423 // mais il faut étudier les interactions avec GenericPort::Get et GenericPort::next
424 template < typename DataManipulator > 
425 struct CalciumCouplingPolicy::EraseDataIdProcessor {
426
427   CalciumCouplingPolicy &_couplingPolicy;
428     
429   EraseDataIdProcessor(CalciumCouplingPolicy &couplingPolicy):
430     _couplingPolicy(couplingPolicy) {};
431
432   template < typename Container >
433   void apply(Container & storedDatas, 
434              typename Container::iterator & wDataIt1 ) const {
435
436     typedef typename Container::key_type   key_type;
437     typedef typename Container::value_type value_type;
438     typedef typename Container::iterator iterator;
439
440 #ifdef MYDEBUG
441     std::cout << "-------- CalciumCouplingPolicy::eraseDataId, storedDatasSize : " << storedDatas.size() << std::endl;
442 #endif
443  
444     if ( _couplingPolicy._storageLevel == CalciumTypes::UNLIMITED_STORAGE_LEVEL ) return;
445  
446     size_t storedDatasSize = storedDatas.size();
447     long   s = storedDatasSize - _couplingPolicy._storageLevel;
448     if (s > 0 ) {
449       size_t dist=distance(storedDatas.begin(),wDataIt1);
450       for (int i=0; i<s; ++i) {
451               //no bug if removed : DataManipulator::delete_data((*storedDatas.begin()).second);
452               DataManipulator::delete_data((*storedDatas.begin()).second);
453               storedDatas.erase(storedDatas.begin());
454       }
455       // Si l'itérateur pointait sur une valeur que l'on vient de supprimer
456       if (dist < s ) {
457         throw(CalciumException(CalciumTypes::CPNTNULL,LOC(OSS()<< "StorageLevel management " 
458                                             << _couplingPolicy._storageLevel << 
459                                             " has just removed the data to send")));
460       }
461     }
462 #ifdef MYDEBUG
463     std::cout << "-------- CalciumCouplingPolicy::eraseDataId, new storedDatasSize : " << storedDatas.size() << std::endl;
464 #endif
465     return;
466
467   }
468 };
469
470
471 // Lorsque cette méthode est appelée depuis GenericPort::Get 
472 // l'expectedDataId n'a pas été trouvé et n'est pas non plus 
473 // encadré (en mode temporel).
474 // Si apply n'effectue pas de traitement particulier la méthode renvoie false
475 // Si le port a déjà reçu une directive de deconnexion STOP une exception est levée
476 // Si le port a déjà reçu une directive de deconnexion CONTINUE, 
477 // on donne la dernière valeur connu et on renvoie true.
478 template < typename DataManipulator > 
479 struct CalciumCouplingPolicy::DisconnectProcessor {
480
481   const CalciumCouplingPolicy  & _couplingPolicy;
482     
483   DisconnectProcessor(const CalciumCouplingPolicy & couplingPolicy):
484     _couplingPolicy(couplingPolicy) {};
485
486   template < typename Container, typename DataId >
487   bool apply(Container & storedDatas,
488              const DataId & expectedDataId,
489              typename Container::iterator & wDataIt1 ) const {
490
491     typedef typename Container::key_type   key_type;
492     typedef typename Container::value_type value_type;
493     typedef typename Container::iterator   iterator;
494
495     // Pas de traitement particulier a effectuer
496 #ifdef MYDEBUG
497     std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK1 ("<< _couplingPolicy._disconnectDirective<<") --------" << std::endl;
498 #endif
499     if ( (_couplingPolicy._disconnectDirective) == (CalciumTypes::UNDEFINED_DIRECTIVE) ) return false;
500   
501 #ifdef MYDEBUG
502     std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK2 --------" << std::endl;
503 #endif
504
505     // TODO : Ds GenericPort::next il faut convertir en CPSTOPSEQ
506     if ( _couplingPolicy._disconnectDirective == CalciumTypes::CP_ARRET )
507       throw(CalciumException(CalciumTypes::CPINARRET,LOC(OSS()<< "CP_ARRET directive" 
508                                            << " interrupts all further data reading")));
509 #ifdef MYDEBUG
510     std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK3 --------" << std::endl;
511 #endif
512
513
514     // S'il n'y a plus de données indique que l'on a pas pu effectuer de traitement
515     // TODO : Dans la gestion des niveaux il faut peut être interdire un niveau ==  0
516     if ( storedDatas.empty() ) 
517       throw(CalciumException(CalciumTypes::CPNTNULL,LOC(OSS()<< "CP_CONT directive" 
518                                           << " is active but no data is available.")));
519     
520     // expectedDataId n'a ni été trouvé dans storedDataIds ni encadré mais il se peut
521     // qu'en mode itératif il ne soit pas plus grand que le plus grand DataId stocké auquel
522     // cas on doit renvoyer une expection car on n'est plus connecté et on ne pourra jamais
523     // fournir de données pour ce dataId.
524 #ifdef MYDEBUG
525     std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK4  " << expectedDataId <<" --------" << std::endl;
526 #endif
527
528     // >= expectedDataId
529     iterator it1 = storedDatas.lower_bound(expectedDataId);
530 #ifdef MYDEBUG
531     std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK5  " << std::endl;
532     for (iterator it=storedDatas.begin();it!=storedDatas.end();++it)
533       std::cout <<" "<<(*it).first ;
534     std::cout <<std::endl;
535 #endif
536
537     // TODO : Il faut en fait renvoyer le plus proche cf IT ou DT
538     if (it1 == storedDatas.end())
539       throw(CalciumException(CalciumTypes::CPNTNULL,LOC(OSS()<< "CP_CONT directive" 
540                                           << " is active but the requested dataId is less or equal to the last one received.")));
541   
542 #ifdef MYDEBUG
543     std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK6 " << std::endl;
544 #endif
545
546     wDataIt1 = storedDatas.end();
547     --wDataIt1;
548 #ifdef MYDEBUG
549     std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor, CP_CONT : " << (*wDataIt1).first << std::endl;
550 #endif
551
552     return true;
553   }
554 };
555
556 #endif