0024044: Performance improvements: Foundation Classes (math)
[occt.git] / src / math / math_DoubleTab.gxx
1 // Copyright (c) 1997-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19 // Lpa, le 7/02/92
20
21
22 #include <math_Memory.hxx>
23 #include <Standard_OutOfRange.hxx>
24 #include <Standard_Failure.hxx>
25 #include <Standard_Integer.hxx>
26
27 // macro to get size of C array
28 #define CARRAY_LENGTH(arr) (sizeof(arr)/sizeof(arr[0]))
29
30 void math_DoubleTab::Allocate()
31 {
32   Standard_Integer RowNumber = UppR - LowR + 1;
33   Standard_Integer ColNumber = UppC - LowC + 1;
34
35   Item** TheAddr = !isAddrAllocated? (Item**)&AddrBuf : 
36     (Item**) Standard::Allocate(RowNumber * sizeof(Item*));
37   Item* Address;
38   if(isAllocated) 
39     Address = (Item*) Standard::Allocate(RowNumber * ColNumber * sizeof(Item));
40   else
41     Address = (Item*) Addr;
42   Address -= LowC;
43   
44   for (Standard_Integer Index = 0; Index < RowNumber; Index++) {
45     TheAddr[Index] = Address;
46     Address += ColNumber;
47   }
48   
49   TheAddr -= LowR;
50   Addr = (Standard_Address) TheAddr;
51 }
52
53 math_DoubleTab::math_DoubleTab(const Standard_Integer LowerRow,
54                                const Standard_Integer UpperRow,
55                                const Standard_Integer LowerCol,
56                                const Standard_Integer UpperCol) :
57   Addr(Buf),
58   isAddrAllocated(UpperRow - LowerRow + 1 > CARRAY_LENGTH(AddrBuf)),
59   isAllocated((UpperRow - LowerRow + 1) * (UpperCol - LowerCol + 1) > CARRAY_LENGTH(Buf)),
60   LowR(LowerRow),
61   UppR(UpperRow),
62   LowC(LowerCol),
63   UppC(UpperCol)
64 {
65   Allocate();
66 }
67
68
69 math_DoubleTab::math_DoubleTab(const Item& Tab,
70                                const Standard_Integer LowerRow,
71                                const Standard_Integer UpperRow,
72                                const Standard_Integer LowerCol,
73                                const Standard_Integer UpperCol) :
74   Addr((void *) &Tab),
75   isAddrAllocated(UpperRow - LowerRow + 1 > CARRAY_LENGTH(AddrBuf)),
76   isAllocated(Standard_False),
77   LowR(LowerRow),
78   UppR(UpperRow),
79   LowC(LowerCol),
80   UppC(UpperCol)
81 {
82   Allocate();
83 }
84
85 void math_DoubleTab::Init(const Item& InitValue) 
86 {
87   for (Standard_Integer i = LowR; i <= UppR; i++) {
88     for (Standard_Integer j = LowC; j <= UppC; j++) {
89       ((Item**) Addr)[i][j] = InitValue;
90     }
91   }
92 }
93
94
95
96 math_DoubleTab::math_DoubleTab(const math_DoubleTab& Other) :
97   Addr(Buf),
98   isAddrAllocated(Other.UppR - Other.LowR + 1 > CARRAY_LENGTH(AddrBuf)),
99   isAllocated((Other.UppR - Other.LowR + 1) * 
100               (Other.UppC - Other.LowC + 1) > CARRAY_LENGTH(Buf)),
101   LowR(Other.LowR),
102   UppR(Other.UppR),
103   LowC(Other.LowC),
104   UppC(Other.UppC)
105 {
106   Allocate();
107
108   Standard_Address target = (Standard_Address) &Value(LowR,LowC);
109   Standard_Address source = (Standard_Address) &Other.Value(LowR,LowC);
110
111   memmove(target,source,
112           (int)((UppR - LowR + 1) * (UppC - LowC + 1) * sizeof(Item)));
113
114 }
115
116
117 void math_DoubleTab::Free()
118 {
119   // free the data
120   if(isAllocated) {
121     Standard_Address it = (Standard_Address)&Value(LowR,LowC);
122     Standard::Free(it);
123   }
124   // free the pointers
125   if(isAddrAllocated) {
126     Standard_Address it = (Standard_Address)(((Item**)Addr) + LowR);
127     Standard::Free (it);
128   }
129   Addr = 0;
130 }
131
132
133
134 void math_DoubleTab::SetLowerRow(const Standard_Integer LowerRow)
135 {
136   Item** TheAddr = (Item**)Addr;
137   Addr = (Standard_Address) (TheAddr + LowR - LowerRow);
138   UppR = UppR - LowR + LowerRow;
139   LowR = LowerRow;
140 }
141
142
143 void math_DoubleTab::SetLowerCol(const Standard_Integer LowerCol)
144 {
145   Item** TheAddr = (Item**) Addr;
146   for (Standard_Integer Index = LowR; Index <= UppR; Index++) {
147     TheAddr[Index] = TheAddr[Index] + LowC - LowerCol;
148   }
149
150   UppC = UppC - LowC + LowerCol;
151   LowC = LowerCol;
152 }
153