Index: trunk/SophyaLib/BaseTools/ndatablock.cc
===================================================================
--- trunk/SophyaLib/BaseTools/ndatablock.cc	(revision 969)
+++ trunk/SophyaLib/BaseTools/ndatablock.cc	(revision 976)
@@ -114,5 +114,5 @@
 //! Copy constructor
 /*!
-  \warning datas are shared if \b a is temporary, cloned if not.
+  \warning datas are \b SHARED with \b a.
  */
 template <class T>
@@ -199,4 +199,31 @@
 
 //! \b Share with \b a if \b temporary, \b clone from \b a if not.
+/*! \warning For most purposes, users don't have to worry with
+             the "temporary" nature of a NDataBlock. That is used
+             internaly to avoid memory allocation in operation
+             like A = B + C + D for instance. The method is not
+             protected to allow users to write complicated functions
+             on NDataBlock.
+  \verbatim
+  ----------------------------------------------------------
+  Pourquoi une complication avec la notion de "temporaire" :
+  ----------------------------------------------------------
+  - Le constructeur par copie partageant les donnees,
+    dans une methode un { NDataBlock<T> result; ...; return result;}
+    ne va pas allouer de la memoire pour retourner "result".
+  - La gestion de temporaire sert quand on enchaine plusieurs
+    operations sur la meme ligne, par exemple : A = B+C+D;
+    Dans ce cas l'objet CD=C+D est d'abord alloue et rempli
+    avec C+D, puis CD est mis a "temporaire".
+    Quand on ajoute B a CD, la methode d'addition va se rendre compte
+    que CD est "temporaire" et additionner B "in-place" dans CD
+    sans allouer une fois de plus de la place (pas d'allocation
+    de place BCD pour mettre B+CD mais une operation CD += B).
+    Si la notion d'objet "temporaire" n'avait pas ete consideree
+    l'addition A = B+C+D aurait alloue de la place pour "CD=C+D"
+    puis pour BCD=B+CD : 2 allocations auraient ete necessaires
+    contre 1 seule dans notre cas de geston de "temporaire".
+  \endverbatim
+*/
 template <class T>
 void NDataBlock<T>::CloneOrShare(const NDataBlock<T>& a)
@@ -473,6 +500,6 @@
 ///////////////////////////////////////////////////////////////
 
-//! Operator = : ND = ND1
-/*! \warning share if \b a is temporary, clone if not */
+//! Operator = : ND = NDa
+/*! \warning Datas are copied (cloned) from \b a. */
 template <class T>
 NDataBlock<T>& NDataBlock<T>::operator = (const NDataBlock<T>& a)
@@ -487,8 +514,5 @@
 if(a.mSz==0)
   throw(SzMismatchError("NDataBlock::operator=A null size \n"));
-if (mSz==0) {  
-  CloneOrShare(a);
-  return *this;
-}
+if (mSz==0) { CloneOrShare(a); return *this; }
 if (a.mSz != mSz)
   throw(SzMismatchError("NDataBlock::operator=A Unequal sizes \n"));
@@ -506,8 +530,6 @@
       <<" mSz="<<mSz<<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp<<endl;
 
-
 if(mSz==0) throw(SzMismatchError("NDataBlock::operator=v null size\n"));
-T *p=Begin(), *pe=End();
-while (p<pe) *p++ = v;
+T *p=Begin(), *pe=End(); while (p<pe) *p++ = v;
 return *this;
 }
@@ -522,6 +544,5 @@
 {
 if(mSz==0) throw(SzMismatchError("NDataBlock::operator+=v null size\n"));
-T *p=Begin(), *pe=End();
-while (p<pe) *p++ += b;
+T *p=Begin(), *pe=End(); while (p<pe) *p++ += b;
 return *this;
 }
@@ -532,6 +553,5 @@
 {
 if(mSz==0) throw(SzMismatchError("NDataBlock::operator-=v null size\n"));
-T *p=Begin(), *pe=End();
-while (p<pe) *p++ -= b;
+T *p=Begin(), *pe=End(); while (p<pe) *p++ -= b;
 return *this;
 }
@@ -542,10 +562,9 @@
 {
 if(mSz==0) throw(SzMismatchError("NDataBlock::operator*=v null size\n"));
-T *p=Begin(), *pe=End();
-while (p<pe) *p++ *= b;
-return *this;
-}
-
-//! Divide by a constant : ND *= b
+T *p=Begin(), *pe=End(); while (p<pe) *p++ *= b;
+return *this;
+}
+
+//! Divide by a constant : ND /= b
 template <class T>
 NDataBlock<T>& NDataBlock<T>::operator /= (T b)
@@ -553,6 +572,5 @@
 if(b==(T) 0) throw(ParmError("NDataBlock::operator/=v divide by zero\n"));
 if(mSz==0) throw(SzMismatchError("NDataBlock::operator/=v null size\n"));
-T *p=Begin(), *pe=End();
-while (p<pe) *p++ /= b;
+T *p=Begin(), *pe=End(); while (p<pe) *p++ /= b;
 return *this;
 }
@@ -562,5 +580,5 @@
 ////////////////////////////////////////////////////////////////////
 
-//! Add a NDataBlock : ND += ND1
+//! Add a NDataBlock : ND += NDa
 template <class T>
 NDataBlock<T>& NDataBlock<T>::operator += (const NDataBlock<T>& a)
@@ -574,5 +592,5 @@
 }
 
-//! Substract a NDataBlock : ND -= ND1
+//! Substract a NDataBlock : ND -= NDa
 template <class T>
 NDataBlock<T>& NDataBlock<T>::operator -= (const NDataBlock<T>& a)
@@ -586,5 +604,5 @@
 }
 
-//! Multiply by a NDataBlock : ND *= ND1
+//! Multiply by a NDataBlock : ND *= NDa
 template <class T>
 NDataBlock<T>& NDataBlock<T>::operator *= (const NDataBlock<T>& a)
@@ -598,5 +616,5 @@
 }
 
-//! Divide by a NDataBlock : ND *= ND1
+//! Divide by a NDataBlock : ND /= NDa
 template <class T>
 NDataBlock<T>& NDataBlock<T>::operator /= (const NDataBlock<T>& a)
@@ -607,12 +625,13 @@
 T *p=Begin(), *pe=End();
 T const *pa=a.Begin();
-while (p<pe) *p++ /= *pa++;
-return *this;
-}
-
-////////////////////////////////////////////////////////////////
-// Pour surcharge de +,-,*,/ : NDataBlock = NDataBlock1+<T>b; //
-//                             NDataBlock = <T>b+NDataBlock1; //
-////////////////////////////////////////////////////////////////
+while (p<pe) *p++ /= *pa++; // Division par zero non protegee
+return *this;
+}
+
+//////////////////////////////////////////////////////////////////
+// Pour surcharge de +,-,*,/ : NDataBlock = NDataBlock1+<T>b;   //
+//                             NDataBlock = <T>b+NDataBlock1;   //
+// Pour la notion de "temporaire" voir blabla dans CloneOrShare //
+//////////////////////////////////////////////////////////////////
 
 //! Add a constant and return NDataBlock : NDret = ND + b
@@ -627,57 +646,53 @@
 }
 
-//! Substract a constant and return NDataBlock : NDret = ND - b
-template <class T>
-NDataBlock<T> NDataBlock<T>::Sub(T b) const
-// Pour A-b
+//! Substract a constant and return NDataBlock : NDret = ND - b or NDret = b - ND
+/*! Substract a constant or from a constant
+   \param fginv==false : performs NDret = ND - b (default)
+   \param fginv==true : performs NDret = b - ND
+*/
+template <class T>
+NDataBlock<T> NDataBlock<T>::Sub(T b,bool fginv) const
+// Pour A-b sauf si fginv==true b-A (- n'est pas commutatif!)
 {
 NDataBlock<T> result; 
 result.CloneOrShare(*this); result.SetTemp(true);
-return result -= b;
-}
-
-//! Substract from a constant and return NDataBlock : NDret = b - ND
-template <class T>
-NDataBlock<T> NDataBlock<T>::SubInv(T b) const
-// Pour b-A
+if(fginv) {
+  T *p=result.Begin(), *pe=result.End();
+  T const *pa=this->Begin();
+  while(p<pe) {*p++ = b - *pa++;}
+} else result -= b;
+return result;
+}
+
+//! Multiply by a constant and return NDataBlock : NDret = ND * b
+template <class T>
+NDataBlock<T> NDataBlock<T>::Mul(T b) const
+// Pour A*b
 {
 NDataBlock<T> result; 
 result.CloneOrShare(*this); result.SetTemp(true);
-T *p=result.Begin(), *pe=result.End();
-T const *pa=this->Begin();
-while(p<pe) {*p++ = b - *pa++;}
+result *= b;
 return result;
 }
 
-//! Multiply by a constant and return NDataBlock : NDret = ND * b
-template <class T>
-NDataBlock<T> NDataBlock<T>::Mul(T b) const
-// Pour A*b
+//! Divide by a constant and return NDataBlock : NDret = ND / b or NDret = b / ND
+/*! Divide by a constant or from a constant
+   \param fginv==false : performs NDret = ND / b (default)
+   \param fginv==true : performs NDret = b / ND
+*/
+template <class T>
+NDataBlock<T> NDataBlock<T>::Div(T b,bool fginv) const
+// Pour A/b sauf si fginv==true b/A (/ n'est pas commutatif!)
 {
 NDataBlock<T> result; 
 result.CloneOrShare(*this); result.SetTemp(true);
-return result *= b;
-}
-
-//! Divide by a constant and return NDataBlock : NDret = ND / b
-template <class T>
-NDataBlock<T> NDataBlock<T>::Div(T b) const
-// Pour A/b
-{
-NDataBlock<T> result; 
-result.CloneOrShare(*this); result.SetTemp(true);
-return result /= b;
-}
-
-//! Divide from a constant and return NDataBlock : NDret = b / ND
-template <class T>
-NDataBlock<T> NDataBlock<T>::DivInv(T b) const
-// Pour b/A
-{
-NDataBlock<T> result; 
-result.CloneOrShare(*this); result.SetTemp(true);
-T *p=result.Begin(), *pe=result.End();
-T const *pa = this->Begin();
-while(p<pe) {*p++ = b / *pa++;}
+ if(fginv) {
+  T *p=result.Begin(), *pe=result.End();
+  T const *pa = this->Begin();
+  while(p<pe) {*p++ = b / *pa++;} // Division par zero non protegee
+} else {
+  if( b == (T) 0 ) throw MathExc("NDataBlock<T>::Div(T)  - Divide by zero ! ");
+  result /= b;
+}
 return result;
 }
@@ -740,5 +755,5 @@
   result.Share(b);
   T *p=result.Begin(), *pe=result.End(); T const *pa=Begin();
-  while(p<pe) {*p = *pa++  / *p; p++;}
+  while(p<pe) {*p = *pa++  / *p; p++;} // Division par zero non protegee
 } else {result.CloneOrShare(*this); result /= b;}
 return result;
Index: trunk/SophyaLib/BaseTools/ndatablock.h
===================================================================
--- trunk/SophyaLib/BaseTools/ndatablock.h	(revision 969)
+++ trunk/SophyaLib/BaseTools/ndatablock.h	(revision 976)
@@ -133,16 +133,12 @@
   // Surcharge d'operateurs: C = A @ x , C = A @ B
   NDataBlock<T> Add(T b) const;
-  NDataBlock<T> Sub(T b) const;
-  NDataBlock<T> SubInv(T b) const;
+  NDataBlock<T> Sub(T b,bool fginv=false) const;
   NDataBlock<T> Mul(T b) const;
-  NDataBlock<T> Div(T b) const;
-  NDataBlock<T> DivInv(T b) const;
+  NDataBlock<T> Div(T b,bool fginv=false) const;
 
   NDataBlock<T> Add(const NDataBlock<T>& b) const;
   NDataBlock<T> Sub(const NDataBlock<T>& b) const;
-  NDataBlock<T> SubInv(const NDataBlock<T>& b) const;
   NDataBlock<T> Mul(const NDataBlock<T>& b) const;
   NDataBlock<T> Div(const NDataBlock<T>& b) const;
-  NDataBlock<T> DivInv(const NDataBlock<T>& b) const;
 
 protected:
@@ -186,5 +182,5 @@
 template<class T>
 inline NDataBlock<T> operator - (T b,const NDataBlock<T>& a)
-                      {return a.SubInv(b);}
+                      {return a.Sub(b,true);}
 //! Multiply datas by a constant and return NDataBlock : ND = NDa * b
 template<class T>
@@ -202,5 +198,5 @@
 template<class T>
 inline NDataBlock<T> operator / (T b,const NDataBlock<T>& a)
-                      {return a.DivInv(b);}
+                      {return a.Div(b,true);}
 
 //! Add datas of two data blocks and return NDataBlock : ND = NDa + NDb
