579c31d811b1e5142841d721c6eeb56423298a81
[occt.git] / src / Interface / Interface_EntityCluster.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14
15 #include <Interface_EntityCluster.hxx>
16 #include <Interface_EntityIterator.hxx>
17 #include <Interface_EntityList.hxx>
18 #include <Standard_NullObject.hxx>
19 #include <Standard_OutOfRange.hxx>
20 #include <Standard_Transient.hxx>
21 #include <Standard_Type.hxx>
22
23 IMPLEMENT_STANDARD_RTTIEXT(Interface_EntityCluster,Standard_Transient)
24
25 // Un Cluster, ce sont 4 entites qui se suivent (dans le principe, nombre fixe,
26 // meme si pas 4). Elles sont remplies depuis 0. Il y a donc autant d Entites
27 // que de Handles non Nuls, plus le fait qu ils sont remplis dans l ordre
28 // Ainsi (avec Next), on consomme 5 Handles pour 4 Entites, avec une pointe
29 // pour 1 et 2 Entites (on reste a 5 Handles)
30 // Suppression : On retasse le Cluster pour que les Nulls soient tjrs a la fin
31 //  ....                        CONSTRUCTEURS                        ....
32 Interface_EntityCluster::Interface_EntityCluster ()    {  }
33
34     Interface_EntityCluster::Interface_EntityCluster
35   (const Handle(Standard_Transient)& ent)
36       {  theents[0] = ent;  }
37
38     Interface_EntityCluster::Interface_EntityCluster
39   (const Handle(Interface_EntityCluster)& ec)
40       {  thenext = ec;  }
41
42     Interface_EntityCluster::Interface_EntityCluster
43   (const Handle(Standard_Transient)& ent,
44    const Handle(Interface_EntityCluster)& ec)
45       {  theents[0] = ent;  thenext = ec;  }
46
47 //  ....                        AJOUT - SUPPRESSION                        ....
48
49     void  Interface_EntityCluster::Append
50   (const Handle(Standard_Transient)& ent)
51 {
52   if (ent.IsNull()) throw Standard_NullObject("Interface_EntityCluster Append");
53   if      (theents[0].IsNull()) theents[0] = ent;
54   else if (theents[1].IsNull()) theents[1] = ent;
55   else if (theents[2].IsNull()) theents[2] = ent;
56   else if (theents[3].IsNull()) theents[3] = ent;
57   else {                                // Si celui-ci est plein ...
58     if (thenext.IsNull()) thenext = new Interface_EntityCluster(ent);
59     else thenext->Append(ent);
60   }
61 }
62
63     Standard_Boolean  Interface_EntityCluster::Remove
64   (const Handle(Standard_Transient)& ent)
65 {
66   if (ent.IsNull()) throw Standard_NullObject("Interface_EntityCluster Remove");
67   Standard_Integer i;
68 //  <ent> est-il ici ? si oui, on a son rang
69   if      (ent == theents[0]) i = 1;
70   else if (ent == theents[1]) i = 2;
71   else if (ent == theents[2]) i = 3;
72   else if (ent == theents[3]) i = 4;
73
74 //  Sinon, passer au suivant, qui peut du coup devenir vide ->
75 //  On enleve le cluster vide de la liste (en principe cest le dernier)
76   else {                                // Pas trouve dans celui-ci ...
77     if (thenext.IsNull()) return Standard_False;
78     Standard_Integer res = thenext->Remove(ent);
79     if (res) thenext = thenext->Next();
80     return Standard_False;
81   }
82   return Remove(i);
83 }
84
85     Standard_Boolean  Interface_EntityCluster::Remove
86   (const Standard_Integer num)
87 {
88   if (num < 1) throw Standard_OutOfRange("EntityCluster : Remove");
89   Standard_Integer n = NbLocal();
90   if (num > n) {
91     if (thenext.IsNull()) throw Standard_OutOfRange("EntityCluster : Remove");
92     Standard_Boolean res = thenext->Remove (num-n);
93     if (res) thenext = thenext->Next();
94     return Standard_False;
95   }
96   for (Standard_Integer j = num; j < n; j --) theents[j-1] = theents[j];
97   theents[3].Nullify();     // On Nullify par la fin
98   return (n == 1);          // Ancien NbLocal == 1  -> devient nul
99 }
100
101 //  ....                        ACCES AUX DONNEES                        ....
102
103     Standard_Integer  Interface_EntityCluster::NbEntities() const 
104 {
105   Standard_Integer nb = NbLocal();
106   if (!thenext.IsNull()) nb += thenext->NbEntities();
107   return nb;
108 }
109
110     const Handle(Standard_Transient)&  Interface_EntityCluster::Value
111   (const Standard_Integer num) const
112 {
113   Standard_Integer nb = NbLocal();
114   if (num <= 0) throw Standard_OutOfRange("Interface EntityCluster : Value");
115   if (num > nb) {
116     if (thenext.IsNull()) throw Standard_OutOfRange("Interface EntityCluster : Value");
117     return thenext->Value(num-nb);
118   }
119   return theents[num-1];  // numerotation a partir de 0
120 }
121
122     void  Interface_EntityCluster::SetValue
123   (const Standard_Integer num, const Handle(Standard_Transient)& ent)
124 {
125   if (ent.IsNull()) throw Standard_NullObject("Interface_EntityCluster SetValue");
126   Standard_Integer nb = NbLocal();
127   if (num <= 0) throw Standard_OutOfRange("Interface EntityCluster : SetValue");
128   if (num > nb) {
129     if (thenext.IsNull()) throw Standard_OutOfRange("Interface EntityCluster : SetValue");
130     thenext->SetValue(num-nb,ent);
131   }
132   else theents[num-1] = ent;  // numerotation a partir de 0
133 }
134
135     void  Interface_EntityCluster::FillIterator
136   (Interface_EntityIterator& iter) const 
137 {
138   if (!theents[0].IsNull()) iter.GetOneItem(theents[0]);
139   if (!theents[1].IsNull()) iter.GetOneItem(theents[1]);
140   if (!theents[2].IsNull()) iter.GetOneItem(theents[2]);
141   if (!theents[3].IsNull()) iter.GetOneItem(theents[3]);
142   if (!thenext.IsNull()) thenext->FillIterator(iter);
143 }
144
145 //  ....                    Actions atomiques internes                    ....
146
147 Standard_Boolean  Interface_EntityCluster::IsLocalFull () const 
148 {
149   // Solaris Forte C++ compiler insisted it couldn't cast this,
150   // even though it seems to do so elsewhere
151   Handle(Standard_Transient) tmp = Handle(Standard_Transient)(theents[3]);
152   return ( !tmp.IsNull() );
153 }
154
155     Standard_Integer  Interface_EntityCluster::NbLocal () const
156 {
157   Standard_Integer nb;
158   if      (!theents[3].IsNull()) nb = 4;
159   else if (!theents[2].IsNull()) nb = 3;
160   else if (!theents[1].IsNull()) nb = 2;
161   else if (!theents[0].IsNull()) nb = 1;
162   else                           nb = 0;
163   return nb;
164 }
165
166     Standard_Boolean  Interface_EntityCluster::HasNext () const 
167       {  return (!thenext.IsNull());  }
168
169     Handle(Interface_EntityCluster)  Interface_EntityCluster::Next () const 
170       {  return thenext;  }