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