|
1 |
|
2 /* |
|
3 * Copyright 2006 The Android Open Source Project |
|
4 * |
|
5 * Use of this source code is governed by a BSD-style license that can be |
|
6 * found in the LICENSE file. |
|
7 */ |
|
8 |
|
9 |
|
10 #ifndef SkTDArray_Experimental_DEFINED |
|
11 #define SkTDArray_Experimental_DEFINED |
|
12 |
|
13 #include "SkTypes.h" |
|
14 |
|
15 #ifdef SK_BUILD_FOR_UNIX |
|
16 #define SK_BUILD_FOR_ADS_12 |
|
17 #endif |
|
18 |
|
19 #if !defined(SK_BUILD_FOR_ADS_12) && !defined(__x86_64__) |
|
20 #define SK_SMALLER_ARRAY_TEMPLATE_EXPERIMENT 1 |
|
21 #else |
|
22 #define SK_SMALLER_ARRAY_TEMPLATE_EXPERIMENT 0 |
|
23 #endif |
|
24 |
|
25 #if SK_SMALLER_ARRAY_TEMPLATE_EXPERIMENT == 0 |
|
26 #include "SkTDArray.h" |
|
27 #define SkIntArray(type) SkTDArray<type> |
|
28 #define SkLongArray(type) SkTDArray<type> |
|
29 #else |
|
30 |
|
31 class SkDS32Array { |
|
32 protected: |
|
33 SkDS32Array(); |
|
34 SkDS32Array(const SkDS32Array& src); |
|
35 SkDS32Array(const int32_t src[], U16CPU count); |
|
36 SkDS32Array& operator=(const SkDS32Array& src); |
|
37 friend int operator==(const SkDS32Array& a, const SkDS32Array& b); |
|
38 int32_t* append() { return this->append(1, NULL); } |
|
39 int32_t* append(U16CPU count, const int32_t* src = NULL); |
|
40 |
|
41 int32_t* appendClear() |
|
42 { |
|
43 int32_t* result = this->append(); |
|
44 *result = 0; |
|
45 return result; |
|
46 } |
|
47 |
|
48 int find(const int32_t& elem) const; |
|
49 int32_t* insert(U16CPU index, U16CPU count, const int32_t* src); |
|
50 int rfind(const int32_t& elem) const; |
|
51 void swap(SkDS32Array& other); |
|
52 public: |
|
53 bool isEmpty() const { return fCount == 0; } |
|
54 int count() const { return fCount; } |
|
55 |
|
56 void remove(U16CPU index, U16CPU count = 1) |
|
57 { |
|
58 SkASSERT(index + count <= fCount); |
|
59 fCount = SkToU16(fCount - count); |
|
60 memmove(fArray + index, fArray + index + count, sizeof(int32_t) * (fCount - index)); |
|
61 } |
|
62 |
|
63 void reset() |
|
64 { |
|
65 if (fArray) |
|
66 { |
|
67 sk_free(fArray); |
|
68 fArray = NULL; |
|
69 #ifdef SK_DEBUG |
|
70 fData = NULL; |
|
71 #endif |
|
72 fReserve = fCount = 0; |
|
73 } |
|
74 else |
|
75 { |
|
76 SkASSERT(fReserve == 0 && fCount == 0); |
|
77 } |
|
78 } |
|
79 |
|
80 void setCount(U16CPU count) |
|
81 { |
|
82 if (count > fReserve) |
|
83 this->growBy(count - fCount); |
|
84 else |
|
85 fCount = SkToU16(count); |
|
86 } |
|
87 protected: |
|
88 #ifdef SK_DEBUG |
|
89 enum { |
|
90 kDebugArraySize = 24 |
|
91 }; |
|
92 int32_t(* fData)[kDebugArraySize]; |
|
93 #endif |
|
94 int32_t* fArray; |
|
95 uint16_t fReserve, fCount; |
|
96 void growBy(U16CPU extra); |
|
97 }; |
|
98 |
|
99 #ifdef SK_DEBUG |
|
100 #define SYNC() fTData = (T (*)[kDebugArraySize]) fArray |
|
101 #else |
|
102 #define SYNC() |
|
103 #endif |
|
104 |
|
105 template <typename T> class SkTDS32Array : public SkDS32Array { |
|
106 public: |
|
107 SkTDS32Array() { SkDEBUGCODE(fTData=NULL); SkASSERT(sizeof(T) == sizeof(int32_t)); } |
|
108 SkTDS32Array(const SkTDS32Array<T>& src) : SkDS32Array(src) {} |
|
109 ~SkTDS32Array() { sk_free(fArray); } |
|
110 T& operator[](int index) const { SYNC(); SkASSERT((unsigned)index < fCount); return ((T*) fArray)[index]; } |
|
111 SkTDS32Array<T>& operator=(const SkTDS32Array<T>& src) { |
|
112 return (SkTDS32Array<T>&) SkDS32Array::operator=(src); } |
|
113 friend int operator==(const SkTDS32Array<T>& a, const SkTDS32Array<T>& b) { |
|
114 return operator==((const SkDS32Array&) a, (const SkDS32Array&) b); } |
|
115 T* append() { return (T*) SkDS32Array::append(); } |
|
116 T* appendClear() { return (T*) SkDS32Array::appendClear(); } |
|
117 T* append(U16CPU count, const T* src = NULL) { return (T*) SkDS32Array::append(count, (const int32_t*) src); } |
|
118 T* begin() const { SYNC(); return (T*) fArray; } |
|
119 T* end() const { return (T*) (fArray ? fArray + fCount : NULL); } |
|
120 int find(const T& elem) const { return SkDS32Array::find((const int32_t&) elem); } |
|
121 T* insert(U16CPU index) { return this->insert(index, 1, NULL); } |
|
122 T* insert(U16CPU index, U16CPU count, const T* src = NULL) { |
|
123 return (T*) SkDS32Array::insert(index, count, (const int32_t*) src); } |
|
124 int rfind(const T& elem) const { return SkDS32Array::rfind((const int32_t&) elem); } |
|
125 T* push() { return this->append(); } |
|
126 void push(T& elem) { *this->append() = elem; } |
|
127 const T& top() const { return (*this)[fCount - 1]; } |
|
128 T& top() { return (*this)[fCount - 1]; } |
|
129 void pop(T* elem) { if (elem) *elem = (*this)[fCount - 1]; --fCount; } |
|
130 void pop() { --fCount; } |
|
131 private: |
|
132 #ifdef SK_DEBUG |
|
133 mutable T(* fTData)[kDebugArraySize]; |
|
134 #endif |
|
135 }; |
|
136 |
|
137 #define SkIntArray(type) SkTDS32Array<type> // holds 32 bit data types |
|
138 #define SkLongArray(type) SkTDS32Array<type> |
|
139 |
|
140 #endif // SK_SMALLER_ARRAY_TEMPLATE_EXPERIMENT |
|
141 |
|
142 #endif // SkTDArray_Experimental_DEFINED |